NOWL #50

来源:互联网 发布:一键重装软件 编辑:程序博客网 时间:2024/05/01 16:00

最近真是智商爆炸,掉下div1也是理所当然的吧,是不是水刷多了啊?

下面是题解
A
http://codeforces.com/contest/233/problem/A
题意:给一个n,构建一个n的排列,使得两次迭代返回本身,不可能则输出-1。
做法:奇数输出-1,偶数把奇偶位互换即可。
代码:

#include <bits/stdc++.h>using namespace std;int main(){    int n;    scanf("%d", &n);    if(n&1)printf("-1\n");    else{        for(int i=1;i<=n;i++){            if(i&1)printf("%d ", i+1);            else printf("%d%c", i-1, i==n?'\n':' ');        }    }}

B
http://codeforces.com/contest/233/problem/B
题意:给一个正整数n,n<=1e18,求方程x2+s(x)xn=0的正整数根。其中s(x)是x的各位和。
做法:显然s(x)不会很大,粗略地记为s(x)<=200(范围显然可以更小);那这样就有x2<x2+s(x)x=n<x2+200x+1000010000=(x+100)210000,
整理一下得n+10000100<x<n,显然这个范围的数不超过100个,那么逐个验证就OK了。
代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;ll s(ll x){    ll ans=0;    while(x){        ans+=x%10;        x/=10;    }    return ans;}int main(){    ll n;    scanf("%I64d", &n);    ll l=(ll)(sqrt(n+10000)-100);    if(l<0)l=0;    ll r=sqrt(n)+1;    for(ll i=l;i<=r;i++){        if(i*i+i*s(i)==n){            printf("%I64d\n", i);            return 0;        }    }    printf("-1\n");}

C
http://codeforces.com/contest/233/problem/C
题意:给一个n,n<=1e5,构造一个100点以内的图,使得图内的三角形正好是n个。
做法:显然100点的完全图是超过1e5个三元组的,那么,我们找到最大的一个siz,使得C(siz,3)<=n,这样这个有siz个点的完全图就用掉了C(siz,3)个三元组,n-=C(siz,3)。然后依次添加点,每个点找到最大的一个num,使得C(num,2)<=n,这样从这个点往完全图连num条线,就用掉了C(num,2)个三元组,n-=C(num,2),一直这样加点直到n是0。实际上这样拆分好像正好能卡过极限数据吧,因为序列是n方级别,所以其实不太好宽松的证明,不过实在不行跑一遍全数据也不是不可以。
代码:

#include <bits/stdc++.h>using namespace std;int ans[105];int g[105][105];int tot;int main(){    memset(g, 0, sizeof(g));    int n;    scanf("%d", &n);    int siz;    for(int i=3;i<=100;i++){        if(i*(i-1)*(i-2)/6>n){            siz=i-1;            break;        }    }    n-=siz*(siz-1)*(siz-2)/6;    tot=0;    while(n){        int tag;        for(int i=2;i<=100;i++){            if(i*(i-1)/2>n){                tag=i-1;                break;            }        }        ans[++tot]=tag;        n-=tag*(tag-1)/2;    }    for(int i=1;i<=siz;i++)for(int j=1;j<=siz;j++)g[i][j]=1;    for(int i=1;i<=tot;i++)for(int j=1;j<=ans[i];j++)g[siz+i][j]=g[j][siz+i]=1;    for(int i=1;i<=siz+tot;i++)g[i][i]=0;    printf("%d\n", siz+tot);    for(int i=1;i<=siz+tot;i++){        for(int j=1;j<=siz+tot;j++){            printf("%d", g[i][j]);        }        printf("\n");    }}
0 0
原创粉丝点击