• Codeforces Round #639 (Div. 1) A~C


    A. Hilbert's Hotel

    题意:给定长为n(2e5)的序列ai,对于所有整数k(-oo ~ +oo),将其变为k+a(k%n),问经过此变化后是否会有两个数字变成同一个数字。

    思路:i+kn在进行变化后仍然相差kn,即%n得到的数字相同。不妨以0~n-1这n个数字作为代表,如果得到的数字中有%n相同的,那么一定可以通过对原数字+kn使得二者变化后相同,如果没有则无论原数字如何变化都不能使得二者变化后相同。所以只需要判断0~n-1进行变化后%n是否有相同的数字即可。

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define dl double
     4 void rd(int &x){
     5  x=0;int f=1;char ch=getchar();
     6  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     7  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
     8 }
     9 void lrd(LL &x){
    10  x=0;int f=1;char ch=getchar();
    11  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
    13 }
    14 const int INF=1e9;
    15 const LL LINF=1e18;
    16 const int N=2e5+10;
    17 using namespace std;
    18 int T;
    19 int n,a[N];
    20 int main(){
    21 // freopen("in.txt","r",stdin);
    22  rd(T);
    23  while(T--){
    24   rd(n);for(int i=0;i<n;i++)rd(a[i]);
    25   for(int i=0;i<n;i++)a[i]=((i+a[i])%n+n)%n;
    26   sort(a,a+n);bool flg=0;
    27   for(int i=0;i<n-1;i++)if(a[i] == a[i+1])flg=1;
    28   if(flg)printf("NO
    ");else printf("YES
    ");
    29  }
    30  return 0;
    31 }
    32 /**/
    View Code

    B. Monopole Magnets

    题意:有两种磁石,N和S,给一个n*m(1e3 * 1e3)的黑白方格,你可以任意的往一些位置上放上S使得每一行和每一列至少有一个S。当N和S在同一行或者同一列且不在一个格子的时候,N可以向S的方向移动一格。问最少需要几个N使得所有的黑格都可以被N遍历到而所有的白格都不能被N遍历到。不合法输出-1。

    思路:考虑一行中存在黑白黑这样的格子,那么无论这一行的S放到哪里,总会将本在黑的N吸引到白格子处。所以白格子必须以前缀或者后缀的形式出现。行和列都是如此,于是可以判断出-1的一种情况。而如果有一行全是白格子,但却没有一列全是白格子,那么无论将S放到这一行的哪个位置,总会将其对应列黑格子中的N吸引过来,于是不存在合法情况,列同理。而当既有空白行又有空白列的时候,我们可以将它们的交界处放上S,它们不会吸引任何的N,同时也保证了纯白行列至少具有一个S。进而我们可以在所有黑格子上放上S,也不会出现将N吸引至白格的情况,N可以在黑格子中任意上下左右移动,于是只需要判断有几个联通的黑格子块,bfs即可。

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define dl double
     4 void rd(int &x){
     5  x=0;int f=1;char ch=getchar();
     6  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     7  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
     8 }
     9 void lrd(LL &x){
    10  x=0;int f=1;char ch=getchar();
    11  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
    13 }
    14 const int INF=1e9;
    15 const LL LINF=1e18;
    16 const int N=1005;
    17 using namespace std;
    18 int n,m;
    19 char s[N];
    20 int a[N][N];
    21 bool vis[N][N];
    22 int cnt;
    23 int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    24 void dfs(int x,int y){
    25  vis[x][y]=1;
    26  for(int i=0;i<4;i++){
    27   int tx=x+dx[i],ty=y+dy[i];
    28   if(a[tx][ty] && (!vis[tx][ty]))dfs(tx,ty);
    29  }
    30 }
    31 void work(){
    32  int cnt1=0,cnt2=0;
    33  for(int i=1;i<=n;i++){
    34   int id1=m+1,id2=0;
    35   for(int j=1;j<=m;j++)if(a[i][j]){id1=j;break;}
    36   for(int j=m;j>=1;j--)if(a[i][j]){id2=j;break;}
    37   if(!id2)cnt1++;
    38   for(int j=id1;j<=id2;j++)
    39    if(!a[i][j]){printf("-1
    ");return ;}
    40  }
    41  for(int j=1;j<=m;j++){
    42   int id1=n+1,id2=0;
    43   for(int i=1;i<=n;i++)if(a[i][j]){id1=i;break;}
    44   for(int i=n;i>=1;i--)if(a[i][j]){id2=i;break;}
    45   if(!id2)cnt2++;
    46   for(int i=id1;i<=id2;i++)
    47    if(!a[i][j]){printf("-1
    ");return ;}  
    48  }
    49  if(cnt1 && (!cnt2)){printf("-1
    ");return ;}
    50  if(cnt2 && (!cnt1)){printf("-1
    ");return ;}
    51  for(int i=1;i<=n;i++)
    52   for(int j=1;j<=m;j++)
    53    if(!vis[i][j] && a[i][j]){cnt++;dfs(i,j);}
    54  printf("%d
    ",cnt);
    55 }
    56 int main(){
    57 // freopen("in.txt","r",stdin);
    58  rd(n);rd(m);
    59  for(int i=1;i<=n;i++){
    60   scanf("%s",s+1);
    61   for(int j=1;j<=m;j++)if(s[j] == '#')a[i][j]=1;
    62  }
    63  work();
    64  return 0;
    65 }
    66 /**/
    View Code

    C. Quantifier Question

    题意:定义f(x1,x2,...,xn)=(x_j1 < x_k1) && (x_j2 < x_k2) && ... && (x_jn < x_kn)。Q_xi表示任意xi或者存在xi。有n(2e5)个xi,输入m(2e5)对关系ji,ki。寻找一个Q_x1,Q_x2,Q_x3,...,Q_xn使得f(x1,x2,...,xn)为真。注意逻辑词的顺序不能发生变化。如"任意x1使得存在x2使得任意x3满足f为真"与"任意x1使得任意x2使得存在x3满足f为真"是不同的。如果有多种方案则需要使得"存在"使用的最少。输出方案,不存在输出-1。

    思路:考虑对于一个小于关系,进行一条连边。如果xi<xj则连i->j的单向边。如果建出来的图没有环,则一定有合法情况,即可以将所有的Q取"存在"。如果有环则不合法。从x1开始考虑,如果其取"存在",则从其开始可以遍历到的点以及可以遍历到它的点,都不能取"任意",因为与其存在大小关系的联系。而如果x1取"任意",情况是相同的,即它能遍历到的和能遍历到它的点都只能取"存在"。所以我们贪心的取"任意"。于是继续考虑x2,如果它从来没有被之前的点遍历到,那么它不受任何约束,同x1可以贪心的取"任意",而如果它被遍历到过,那么它只能取"存在",并且他能遍历到的点和能遍历到它的点也不再能取"任意"了,因为与其存在大小关系。我们可以建两张图来实现这个过程,一张图正向建边,另一张图反向建边,遍历的时候通过vis标记可以使得最终复杂度是O(n)。

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define dl double
     4 void rd(int &x){
     5  x=0;int f=1;char ch=getchar();
     6  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     7  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
     8 }
     9 void lrd(LL &x){
    10  x=0;int f=1;char ch=getchar();
    11  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
    13 }
    14 const int INF=1e9;
    15 const LL LINF=1e18;
    16 const int N=2e5+10;
    17 using namespace std;
    18 int n,m;
    19 vector<int>a[N];
    20 vector<int>b[N];
    21 int in[N];
    22 queue<int>S;
    23 void check(){
    24  for(int i=1;i<=n;i++)if(!in[i])S.push(i);
    25  while(!S.empty()){
    26   int u=S.front();S.pop();
    27   for(int i=0;i<a[u].size();i++)
    28    if(!(--in[a[u][i]]))S.push(a[u][i]);
    29  }
    30  for(int i=1;i<=n;i++)if(in[i]){printf("-1
    ");exit(0);}
    31 }
    32 int ans[N];
    33 bool vis[N][3];
    34 void dfs1(int x){
    35  vis[x][1]=1;
    36  for(int i=0;i<a[x].size();i++)
    37   if(!vis[a[x][i]][1])dfs1(a[x][i]);
    38 }
    39 void dfs2(int x){
    40  vis[x][2]=1;
    41  for(int i=0;i<b[x].size();i++)
    42   if(!vis[b[x][i]][2])dfs2(b[x][i]);
    43 }
    44 int main(){
    45 // freopen("in.txt","r",stdin);
    46  rd(n);rd(m);
    47  for(int i=1;i<=m;i++){
    48   int x,y;rd(x);rd(y);
    49   a[x].push_back(y);
    50   b[y].push_back(x);
    51   in[y]++; 
    52  }
    53  check();
    54  int cnt=0;
    55  for(int i=1;i<=n;i++){
    56   if((!vis[i][1]) && (!vis[i][2]))cnt++,ans[i]=1;
    57   if(!vis[i][1])dfs1(i);
    58   if(!vis[i][2])dfs2(i); 
    59  }
    60  printf("%d
    ",cnt);
    61  for(int i=1;i<=n;i++)if(ans[i])putchar('A');else putchar('E');
    62  return 0;
    63 }
    64 /**/
    View Code
  • 相关阅读:
    android中的逐帧动画
    在android项目中使用FontAwesome字体
    java中Proxy类初探
    SwipeRefreshLayout基本使用
    【uni-app】condition 启动模式配置,仅开发期间生效
    【uni-app】底部tabbar导航栏右上角添加数字标记
    【uni-app】设置导航条(标题、导航条颜色、加载动画等)
    errno的定义
    S3C6410串口平台设备注册流程分析
    内核线程
  • 原文地址:https://www.cnblogs.com/hyghb/p/12865635.html
Copyright © 2020-2023  润新知