【Codeforces】Round #485 Div2

传送门CodeforcesRound#485Div2


A Infinity Gauntlet

不想说什么……emmm语法题??

#include<bits/stdc++.h>
using namespace std;
int n,m;
int exi[10];
char s[33];
int main(){
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;++i){
        scanf("%s",s);
        if(s[0]=='p'){
            exi[1]=1;
        }else if(s[0]=='g'){
            exi[2]=1;
        }else if(s[0]=='b'){
            exi[3]=1;
        }else if(s[0]=='o'){
            exi[4]=1;
        }else if(s[0]=='r'){
            exi[5]=1;
        }else if(s[0]=='y'){
            exi[6]=1;
        }
    }
    printf("%d\n",6-n);
    if(!exi[1]) printf("Power\n");
    if(!exi[2]) printf("Time\n");
    if(!exi[3]) printf("Space\n");
    if(!exi[4]) printf("Soul\n");
    if(!exi[5]) printf("Reality\n");
    if(!exi[6]) printf("Mind\n");
}

B High School: Become Human

取一个log,n次幂就变成了乘以n。
我们比较 x y y x 就是比较 y l o g ( x ) x l o g ( y )
之前一直WA是因为本蒟蒻居然以为只有x==y时,才会有=的情况QWQ
然而 2 4 就是等于的,血WA…
最好不要用double变量存下来这个值,据说会被卡精度

#include<bits/stdc++.h>
#define db double 
using namespace std;
int x,y,t;

int main(){
    scanf("%d%d",&x,&y);
    if(log(x)*y==log(y)*x){printf("=\n");}
    else if(log(x)*y<log(y)*x) printf("<\n");
    else printf(">\n");
}

C Three displays

dp贪心傻逼题

#include<bits/stdc++.h>
const int inf=2e9; 
using namespace std;
int f[3010][3],n,c[3010],s[3010];
int ans=inf;

int main(){
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;++i){f[i][1]=f[i][2]=inf;scanf("%d",&s[i]);}
    for(i=1;i<=n;++i) scanf("%d",&c[i]);
    for(i=1;i<=n;++i){
        f[i][0]=c[i];
        for(j=1;j<i;++j){
            if(s[j]<s[i]){
                f[i][1]=min(f[i][1],f[j][0]+c[i]);
                if(f[j][1]<inf){
                    f[i][2]=min(f[i][2],f[j][1]+c[i]);
                }
            }
        }
    }
    for(i=3;i<=n;++i) ans=min(ans,f[i][2]);
    if(ans>=inf) printf("-1\n");
    else printf("%d\n",ans); 
}

D Fair

k <= 100
我们直接k次bfs找到每个点离每种颜色最近的距离。求每个答案的时候sort把前s个加起来就好了。
本蒟蒻一开始血T…因为bfs的时候只加了一个dis=0的点进去跑(当然会血T),把所有加进去就过了。

#include<bits/stdc++.h>
using namespace std;
const int inf=2e9,N=1e5+5;
int d[N][102],a[N],n,k,cur,m,s,vis[N];
int head[N],to[N<<1],nxt[N<<1],tot,dir[102];
queue<int>Q;
vector<int>in[102];
inline int rd()
{
    char ch=getchar();int x=0,f=1;
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    return x*f;
}

inline void lk(int u,int v)
{to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}

inline void bfs(int col)
{
    int i,j,x;
    for(i=in[col].size()-1;i>=0;i--){
        j=in[col][i];Q.push(j);d[j][col]=0;vis[j]=1;
    }
    while(!Q.empty()){
        x=Q.front();Q.pop();vis[x]=0;
        for(i=head[x];i;i=nxt[i]){
            j=to[i];
            if(d[j][col]>d[x][col]+1){
                d[j][col]=d[x][col]+1;
                if(!vis[j]){
                    Q.push(j);
                    vis[j]=1;
                }
            }
        }
    }
}

int main(){
    int i,j,x,y;
    n=rd();m=rd();k=rd();s=rd();
    for(i=1;i<=n;++i) 
      for(j=1;j<=k;++j)
       d[i][j]=inf;
    for(i=1;i<=n;++i) {a[i]=rd();in[a[i]].push_back(i);}
    while(m--){x=rd();y=rd();lk(x,y);lk(y,x);}
    for(i=1;i<=k;++i) bfs(i);
    for(i=1;i<=n;++i){
        cur=0;
        sort(d[i]+1,d[i]+k+1);
        for(j=1;j<=s;++j) cur+=d[i][j];
        printf("%d ",cur);
    }
} 

E Petr and Permutations

这是一道水题。不过本蒟蒻考的时候还是血WA(可能是没有脑子吧)。
直接贪心找到最小交换多少次可以得到当前序列。
可知若剩下的操作次数为偶,则一定成立。
判一下3n减去当前次数是否为偶即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int cnt,n,a[N],in[N];

int main(){
    int i,j,t;
    scanf("%d",&n);
    for(i=1;i<=n;++i){scanf("%d",&a[i]);in[a[i]]=i;}
    for(i=1;i<=n;++i){
        if(a[i]!=i){
           j=in[i];
           a[j]=a[i];in[a[i]]=j;a[i]=i; 
           cnt++;
        }
    }
    if((3*n-cnt)%2==0) printf("Petr\n");
    else printf("Um_nik\n");
}

F AND Graph

全集当然为2^n-1。
一开始的思路是1-n枚举,枚举每个数异或全集的子集(就是可以连的数),同一个自己的用并查集连起来。最后查一下有多少了独立集就好了。
果不其然TLE…
后来发现并不需要这么麻烦,我们处理前面的数时会连到后面的数,处理后面的数时再返回来又会重复处理多次。
其实我们只需要O(n)dfs一遍就好了

#include<bits/stdc++.h>
using namespace std;
const int N=(1<<22)+10;
int n,m,exi[N],a[N],v[N],ans,al;

inline void dfs(int x)
{
    if(v[x]) return;
    v[x]=1;
    if(exi[x]) dfs(al^x);
    for(int i=0;i<n;++i){
        if(x&(1<<i)){
            dfs(x^(1<<i));
        }
    } 
}

int main(){
    int i,j,cur,now,q,p;
   scanf("%d%d",&n,&m);al=(1<<n)-1;
   for(i=1;i<=m;++i){scanf("%d",&a[i]);exi[a[i]]=1;}
   for(i=1;i<=m;++i){
        if(!v[a[i]]){ans++;v[a[i]]=1;dfs(al^a[i]);}
    }   
   printf("%d\n",ans);
}

这场真是水题大放送…
大家快来AK全场吧(雾

猜你喜欢

转载自blog.csdn.net/corsica6/article/details/80594344