感觉这次周赛的题目相当不错。
写不出合法的数字包括两种情况,1是能够写出的数字Si大于Si-2但是超过了n,2是Si没超过n但是小于等于Si-2了。
这就说明胜利者的最后一步一定是使用了最小的那个数字(否则只要他使用非最小数字且合法,对手都可以使用最小数字来写出合法数字),在此之后再使用任何数字都会超出n。所以对手必败。
那么最先达到这个状态的就是胜利者。那么达到这个状态的最后一步也一定是使用了最小的那个数字。
同理不断递推。最后根据奇偶性判断是谁最后使用了最小的那个数字即可。
取最小的数为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;
}
理解的还不是很透彻,就贴一下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;
}