感觉这次周赛的题目相当不错。
HDU 4371
写不出合法的数字包括两种情况,1是能够写出的数字Si大于Si-2但是超过了n,2是Si没超过n但是小于等于Si-2了。
这就说明胜利者的最后一步一定是使用了最小的那个数字(否则只要他使用非最小数字且合法,对手都可以使用最小数字来写出合法数字),在此之后再使用任何数字都会超出n。所以对手必败。
那么最先达到这个状态的就是胜利者。那么达到这个状态的最后一步也一定是使用了最小的那个数字。
同理不断递推。最后根据奇偶性判断是谁最后使用了最小的那个数字即可。
CodeForces 354C
取最小的数为minn,如果minn小于等于k+1,那么minn就是答案。因为所有ai对它取余结果都小于等于k。
当minn大于k+1的时候,可以枚举d从minn到k+1,由大到小,第一次满足所有ai%d<=k的d就是答案。
当ai%d>k的时候,可以直接将d自减1直至ai%d==k,而不必等到所有都结束再自减1.
时间复杂度是O(n+k)
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define MAXN 300005 #define INF 2139062143 #define inf -2139062144 #define ll long long using namespace std; int arr[MAXN]; int main() { int n,k; scanf("%d%d",&n,&k); for(int i=0; i<n; ++i) scanf("%d",&arr[i]); sort(arr,arr+n); if(arr[0]<=k+1) printf("%d\n",arr[0]); else { int d=arr[0]; while(1) { bool update=false; for(int i=0; i<n; ++i) { while((arr[i]%d)>k) { d--; update=true; } } if(!update) break; } printf("%d\n",d); } return 0; }
CodeForces 353D
理解的还不是很透彻,就贴一下CF上某位大神的思路吧。
1. The answer is the number of seconds needed to move the last girl to the finish place.
2. The number of seconds needed for girl i
is at least the number of seconds needed forgirl i - 1
+ 1.
3. The number of seconds needed for girl i
is at least the distance between the initial position and the finish position.
4. Each girl i
will move as soon as she can, so she will be right at the back of thegirl i - 1
or take at most dist(i)
seconds to follow thegirl i - 1
.
so we can calculate the T(i) = max(T(i-1) + 1, dist(i))
and the answer is justT(lastGirl)
.
依此写的代码。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define MAXN 1000005 #define INF 2139062143 #define inf -2139062144 #define ll long long using namespace std; char str[MAXN]; int main() { scanf("%s",str); int t=0,pos=0; while(str[pos]=='F') pos++; for(int i=pos,n=pos;str[i];++i) { if(str[i]=='F') { t=max(t+1,i-n) ; n++; } } printf("%d\n",t); return 0; }