首页 > 代码库 > PA 2011 Round 3 prz题解

PA 2011 Round 3 prz题解

题目大意,现在要走过一条斑马线,斑马线是由n条交替的黑条和白条构成的,第一条是黑条。脚的长度是s。要求在走的过程中,他脚的任何一部分都不能碰到象征邪恶的黑条。第一条之前和第n条之后的部分都是白色的,可以任意选择第一条之前的位置出发。但出发位置一旦选定,之后每一步的长度都必须是k。请你判断有没有可能在不碰到黑条的情况下通过斑马线,即走到第n条之后。

 

此题同样是模拟赛题!!!

我现在已经非常质疑自己的智商了,为什么每次都是离正解只差一步呢,每次都不能换一个思路去想一想。

先说说我的错误解法:我列了n个不等式,判断它能不能踩到黑块,i*k-x>=a[i],i*k-x+s<=a[i+1]-kuan[i+1],i为黑块,但是走几步是一个问题,还有这一个白块可不可以走到也是一个问题,所以正确的处理方法应该是。。。。。。。

 

正解:因为白块不一定要走到,所以我们枚举只要判断能不能不走到黑块就行了,我们首先将每一个黑块的起始位置和结束位置mod k,并将它对应到(0,k-1)的一块区间内,如果x>y,则对应到(x,k-1),(0,y)中,判断有没有属于(0,k-1)中的点没有被覆盖到的情况。

但还要注意一个问题,如果一个黑块长度大于k-s+1,那么是怎么也不行的,因为它怎么也跨不过去。

这道题很多人说用开区间好处理,其实闭区间也很好处理。

 

本题总结:现在经常忘了一样东西就是mod,每次都是利用i来控制范围,却忘记了i这个变量的不确定性,对于不确定问题,mod是一个很好的武器,因为它和i没有关系,利用mod可以大大减小程序复杂度和思维复杂度。以后不能忘了

  1 #include<iostream>  2 #include<cstdio>  3 #include<algorithm>  4 using namespace std;  5 long long p[500005];  6 struct node  7 {  8     int from,to;  9 }a[500005]; 10 int n; 11 int s,k; 12 int T; 13 int m; 14 long long len; 15 void read(int &x){ 16     char ch = getchar(); while (ch < 0 || ch > 9) ch = getchar(); 17     for (x = 0; ch >= 0 && ch <= 9; ch = getchar()) x = x*10+ch-48; 18 } 19 bool cmp(node u,node v) 20 { 21     if(u.from!=v.from)return u.from<v.from; 22     return u.to>v.to; 23 } 24 bool rt; 25 int l,r; 26 int main() 27 { 28     read(T); 29     while(T--) 30     { 31         len=0; 32         rt=false; 33         read(s); 34         s--; 35         read(k); 36         read(n); 37         for(int i=1;i<=n;i++) 38         { 39             int x; 40             read(x); 41             len+=x; 42             p[i]=len; 43         } 44         m=0; 45         for(int i=1;i<=n;i+=2) 46         { 47             if(p[i]-p[i-1]>=k-s) 48             { 49             //    cout<<p[i]-p[i-1]<<endl; 50                 puts("NIE"); 51                 rt=true; 52                 break; 53             } 54             long long x=p[i-1]-s,y=p[i]-1; 55             x=(x%k+k)%k; 56             y=y%k; 57         //    cout<<x<<" "<<y<<endl; 58             if(x<=y){ 59                 a[++m].from=x; 60                 a[m].to=y; 61             } 62             else 63             { 64                 a[++m].from=x; 65                 a[m].to=k-1; 66                 a[++m].from=0; 67                 a[m].to=y; 68             } 69         } 70         if(rt)continue; 71     //    cout<<"find"; 72         sort(a+1,a+m+1,cmp); 73         if(a[1].from>0) 74         { 75             puts("TAK"); 76             continue; 77         } 78         l=a[1].from;r=a[1].to; 79         /*for(int i=1;i<=m;i++) 80         printf("%d %d\n",a[i].from,a[i].to);*/ 81         for(int i=2;i<=m;i++) 82         { 83         //    cout<<a[i].from<<" "<<r<<endl; 84             if(a[i].from>r+1) 85             { 86                 //cout<<i<<r<<endl; 87                 rt=true; 88                 puts("TAK"); 89                 break; 90             } 91             if(a[i].from<=r+1 && a[i].to>=r) 92             { 93                 r=a[i].to; 94             } 95         } 96         if(rt)continue; 97         if(r<k-1) 98         { 99             puts("TAK");100         }101         else102         {103             puts("NIE");104         }105     }106     return 0;107 }108                 109             
View Code