codeforces--280--
其实本场 很水 = =B C都犯了sb错误挂了..
B挂在 自己代码里没有考虑N=1的情况
C挂在 在Int向LL进行强制转换的时候 先溢出了 以后应该这样写 1LL * x * y 或者直接将x y定义为LL
D E porker帮忙= =解释 明天给 睡觉了 3点半了 我擦
B
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 int n , l; 6 const int size = 1010; 7 int a[size]; 8 9 double solve( ) 10 { 11 double ans = max( a[0] , l-a[n-1] ); 12 for( int i = 1 ; i<n ; i++ ) 13 { 14 ans = max( ans , (a[i]-a[i-1])*1.0/2 ); 15 } 16 return ans; 17 } 18 19 int main() 20 { 21 double ans; 22 while( ~scanf("%d %d",&n,&l ) ) 23 { 24 for( int i = 0 ; i<n ; i++ ) 25 { 26 scanf( "%d",&a[i] ); 27 } 28 sort( a , a+n ); 29 ans = solve( ); 30 printf( "%.10lf\n",ans ); 31 } 32 return 0; 33 }
C
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 typedef __int64 LL; 6 const int size = 100010; 7 struct data 8 { 9 int a , b; 10 }node[size]; 11 12 bool cmp( const data p , const data q ) 13 { 14 return p.b < q.b; 15 } 16 17 int main() 18 { 19 int r; 20 LL ans , sum , temp , n , avg; 21 while( ~scanf("%I64d %d %I64d",&n,&r,&avg) ) 22 { 23 sum = 0; 24 ans = 0; 25 for( int i = 0 ; i<n ; i++ ) 26 { 27 scanf( "%d %d",&node[i].a,&node[i].b ); 28 sum += node[i].a; 29 } 30 if( sum >= avg*n ) 31 { 32 printf( "0\n" ); 33 } 34 else 35 { 36 sum = avg*n - sum; 37 sort( node , node+n , cmp ); 38 for( int i = 0 ; i<n ; i++ ) 39 { 40 if( sum<=0 ) 41 break; 42 if( r-node[i].a > 0 ) 43 { 44 temp = min( (LL)r-node[i].a , sum ); 45 sum -= temp; 46 ans += (LL)(temp * node[i].b); 47 } 48 } 49 printf( "%I64d\n",ans ); 50 } 51 } 52 return 0; 53 }
D
就是说A射完X枪的时候 B射完了Y枪 怪物有k滴血 我们要判断当怪物血为0的那一刻是被谁打死的 A or B or both<就是说本来还有2滴血 2个人正好在这一时刻同时打枪 那么正好变成了血量为0 , 就是说Both>
其实 你可以发现A射完x枪 B射完y枪 其实是等价于A射完 x/gcd(x,y) B射完 y/gcd(x,y)的。 这可以帮我们很大的减小数据规模 不然我们都可以直接暴力模拟了
不仅仅是减小了数据规模 而且我们保证了在A没有射出第X枪之前 A B不可能在同一时刻一起打枪
and k % (x+y) < x是x/=gcd(x,y) y 同理 > 与去击杀K滴血的怪是一样的 这也是个很重要的减小规模 因为我们也相当与去除 k/(x+y)次轮的射击 因为每次都是相同的
所以 我现在就可以枚举计算了 枚举的变量是 第几枪 从 1->x+y-1之间
if判断就是说A与B谁先射这第I枪 A/x < B/y 因为整数除法会取整 所以需要移项用乘法进行计算 即 A*y < B*x result就是记录第 i 枪是谁射的.
我想 最重要的一步操作是 能否想到gcd处理。
= =
本题也可以通过二分时间来做。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 4 long long gcd(long long a, long long b) { 5 while (b) { 6 long long c = a % b; 7 a = b; 8 b = c; 9 } 10 return a; 11 } 12 13 bool result[2001000]; 14 15 int main() { 16 int n; 17 long long x, y; 18 cin >> n >> x >> y; 19 long long g = gcd(x, y); 20 x /= g; 21 y /= g; 22 long long sum = x + y; 23 int shotsA = 0, shotsB = 0; 24 for (int i = 1; i < sum; i++) { 25 int newshotA = shotsA + 1; 26 int newshotB = shotsB + 1; 27 if (newshotA * y < newshotB * x) { 28 shotsA = newshotA; 29 result[i] = true; 30 } 31 else { 32 shotsB = newshotB; 33 result[i] = false; 34 } 35 } 36 while (n--) { 37 long long a; 38 cin >> a; 39 a = a % sum; 40 if (a == 0 || a == sum - 1) { 41 cout << "Both" << endl; 42 } 43 else if (result[a]) { 44 cout << "Vanya" << endl; 45 } 46 else { 47 cout << "Vova" << endl; 48 } 49 } 50 }
E
E我讲不大清楚 = = 有点乱。
首先你要得出一个结论:任何一个点 走n步 都将回到起点 因为 ( x + n*dx ) % n == ( y + n*dy ) % n == 0
同时 又有一个数论中的知识点 在 gcd( a , c ) = 1 的情况下 a * b % c (0<=b<=c-1)的值将会是[0,c-1]区间的任意一个值 可以这样说 得到的将是[0,c-1]一共c个数的任意序列 那么因为 题目告诉了我们 gcd( dx , n ) = gcd( dy , n ) = 1 所以那就可以得到我们从任意一点走n步回到起点得到的这条回路 都是[0,n-1]的独一无二的坐标 就是说没有2个拥有相同的横坐标 或者 纵坐标. 那么这个回路中的任意一点都是属于这个环的 我们想个方法来区分这么多不同的环。 我们通过一个 特征值来区分。
因为环上的每个点 横 纵坐标不相同 我可以取纵坐标Y=0 横坐标x为特征值 来对应不同的环。
其实就是说 对于每个点 在自身所在的环内 查找出一个点 y = 0 x为特征值来用counts数组记录
那就是说 y + k*dy = 0 (mod)n 就表示<x,y>走k步可以走到纵坐标是0的点 移项处理就是 k * dy = (n-y)mod(n)
我们可以预处理将所有 k * dy都计算出来 将k计录在 table[n-y]中 这样我每次通过 y 找k的时候 都可以在table[n-y]里面找
打表O(n) 查询O(1)
amazing .
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 int table[1000010]; 6 int counts[1000010]; 7 8 int main() { 9 int n, m, dx, dy; 10 cin >> n >> m >> dx >> dy; 11 int y = 0; 12 for (int i = 0; i < n; i++) { 13 table[n - y] = i; 14 y += dy; 15 y %= n; 16 } 17 table[0] = table[n]; 18 memset(counts, 0, sizeof(counts)); 19 int result = 0; 20 long long locx, locy; 21 while (m--) { 22 long long x, y; 23 cin >> x >> y; 24 long long k = table[y]; 25 long long newx = (x + k * dx) % n; 26 counts[newx]++; 27 if (counts[newx] > result) { 28 result = counts[newx]; 29 locx = x; 30 locy = y; 31 } 32 } 33 cout << locx << " " << locy << endl; 34 }
today:
where'd you go