Sdust ACM Weekly #5

感觉这次周赛的题目相当不错。

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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值