Codeforces Round #495 (Div. 2)

A.
直接模拟或者统计相邻两点距离与d*2的关系即可。
当时写的直接模拟,代码不是很好看

#include<cstdio>
#include<iostream>
#include<cmath>
#include<set>
using namespace std;
int loc[105];
int main()
{
    int n,d,i,j,k,cnt=0;
    cin>>n>>d;
    set<int>ans;
    if(n==1){
        cout<<2<<endl;return 0;
    }
    for(i=1;i<=n;i++)cin>>loc[i];
    for(i=2;i<n;i++){
        if(abs(loc[i-1]-loc[i]+d)<d);
        else ans.insert(loc[i]-d);
        if(abs(loc[i+1]-loc[i]-d)<d);
        else ans.insert(loc[i]+d);
    }
    //cnt+=2;
    if(abs(loc[2]-loc[1]-d)<d);
    else ans.insert(loc[1]+d);
    if(abs(loc[n-1]-loc[n]+d)<d);
    else ans.insert(loc[n]-d);
    cout<<ans.size()+2<<endl;

    return 0;
}

B.
结论题,串为01010101的形式时一定是最优的…证明…不懂

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
    int n,m,i,j,sit=0;
    cin>>n;
    string ans;
    for(i=1;i<=n;i++){
        ans+=char('0'+sit);
        sit^=1;
    }
    cout<<ans<<endl;

    return 0;
}

C.
从左往右扫,如果机器人上的数是i,那么它一定会在遇到第一个i的时候停下,所以所有出现过的数字都不必统计。如果机器人上的数字在位置pos处出现了,那么以这个数i为第一个的pair数就是pos+1,n之间不同数字的个数,这可以通过从右往左的预处理搞出来

#include<cstdio>
#include<iostream>
#include<set>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
typedef pair<int,int>P;
int diff[100005];
int main()
{
    int n,i,j,k;
    cin>>n;
    int num[100005];
    for(i=1;i<=n;i++)scanf("%d",&num[i]);
    set<int>app;
    for(i=n;i;i--){
        if(app.count(num[i]))
            diff[i]=diff[i+1];
        else{
            diff[i]=diff[i+1]+1;app.insert(num[i]);
        }
    }
    app.clear();
    long long ans=0;
    for(i=1;i<=n;i++){
        if(app.count(num[i]))continue;
        ans+=diff[i+1];app.insert(num[i]);
    }
    cout<<ans<<endl;

    return 0;
}

D.
这里写图片描述

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=2000050;
int t,x,cnt[N],Max=0,dis=0,ccnt[N];

bool solve(int n,int m)
{
    int x=dis,y=m-(Max-(n-dis));
    if(x<=0 || y<=0 || x>n || y>m)return 0;
    memset(ccnt,0,sizeof(ccnt));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            ccnt[abs(x-i)+abs(y-j)]++;//统计在这种情况下每个数的出现次数是否与题目呢给定的相同
        }
    for(int i=1;i<=t;i++)if(ccnt[i]!=cnt[i])return 0;
    printf("%d %d\n%d %d\n",n,m,x,y);return 1;
}

int main()
{
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
        scanf("%d",&x),cnt[x]++,Max=max(Max,x);//统计各个数出现次数,求b
    if(cnt[0]!=1)return puts("-1")*0;
    if(t==1)return puts("1 1\n1 1\n")*0;
    for(int i=1;i<=Max;i++){
        if(cnt[i]>4*i)return puts("-1")*0;
        if(cnt[i]<4*i && !dis)dis=i;//求i
    }
    for(int i=1;i*i<=t;i++)
        if(t%i==0){
            if(solve(i,t/i))return 0;
            if(solve(t/i,i))return 0;
        }


        return puts("-1")*0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值