zoukankan      html  css  js  c++  java
  • Codeforces Round #369 (Div. 2)

    Problem A Bus to Udayland

    题目大意

      公交车上有些位置能做,有些不能坐,问是否有两个相邻的位置。

    解题分析

      找到并列的两个O就行。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 int n;
    32 char s[1008][10];
    33 int main(){
    34     scanf("%d",&n);
    35     rep(i,1,n) scanf("%s",s[i]);
    36     int flag=0;
    37     rep(i,1,n){
    38         if (s[i][0]=='O' && s[i][1]=='O'){
    39             s[i][0]=s[i][1]='+';
    40             flag=1;
    41             break;
    42         }
    43 
    44         if (s[i][3]=='O' && s[i][4]=='O'){
    45             s[i][3]=s[i][4]='+';
    46             flag=1;
    47             break;
    48         }
    49     }
    50     if (flag){
    51         printf("YES
    ");
    52         rep(i,1,n) puts(s[i]);
    53     }
    54     else printf("NO
    ");
    55 }
    View Code

    Problem B Chris and Magic Square

    题目大意

      一个n*n(n<=500)的矩形中有一个格子为空,问是否能填上某个数,使得每行每列以及主对角线之后均相等。

    解题分析

      n=1特判。n>=2找出某个可能合法的解,填入后再验证一下。 记得开long long。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 
    32 int n,x,y;
    33 LL a[1008][1008];
    34 LL work(){
    35     LL sum=0;
    36     rep(i,1,n) if (i!=x)
    37     {
    38         rep(j,1,n) sum+=a[i][j];
    39         break;
    40     }
    41     LL op=0;
    42     LL cnt=0;
    43     rep(j,1,n) cnt+=a[x][j];
    44     op=sum-cnt;
    45     a[x][y]=op;
    46     if (op<=0) return -1;
    47     rep(i,1,n) 
    48     {
    49         cnt=0;
    50         rep(j,1,n) cnt+=a[i][j];
    51         if (cnt!=sum) return -1;
    52     }
    53     rep(j,1,n) 
    54     {
    55         cnt=0;
    56         rep(i,1,n) cnt+=a[i][j];
    57         if (cnt!=sum) return -1;
    58     }
    59     cnt=0;
    60     rep(i,1,n) cnt+=a[i][i];
    61     if (cnt!=sum) return -1;
    62 
    63     cnt=0;
    64     rep(i,1,n) cnt+=a[i][n-i+1];
    65     if (cnt!=sum) return -1;    
    66 
    67     return op; 
    68 
    69 
    70 }
    71 int main(){
    72     scanf("%d",&n);
    73     rep(i,1,n) rep(j,1,n) 
    74     {
    75         scanf("%d",&a[i][j]);
    76         if (a[i][j]==0) { x=i; y=j; }
    77     }
    78     if (n==1)
    79     {
    80         printf("1
    ");
    81         return 0;
    82     }
    83     printf("%I64d
    ",work());
    84 }
    View Code

    Problem C Coloring Trees

    题目大意

      有n棵树排成一列,一共有m种颜料,有些树被涂了颜色,有些树没有。

      可以花费a[i][j]的代价给第i棵树涂上j的颜色。

      问给每棵树涂上颜色后,将树恰好分成k段的最小花费。(连续颜色相同的最长区间为一段)

      n,m,k<=100

    解题分析

      只想了个n^4的DP。。还有n^3的做法。

      dp[i][j][k]表示做到第i棵树,分成了j段,第i-1棵树的颜色为k。

      之后枚举第i棵树的颜色转移即可。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const LL INF = 2000000000000000ll;
    30 /**************************************************************************/ 
    31 
    32 int n,m,len;
    33 LL dp[108][108][108];
    34 LL cost[108][108];
    35 int c[108]; 
    36 
    37 void up(LL &x,LL y){
    38     x = min(x,y);
    39 }
    40 int main(){
    41     rep(i,0,100) rep(j,0,100) rep(k,0,100) dp[i][j][k]=INF; 
    42     scanf("%d%d%d",&n,&m,&len);
    43     rep(i,1,n) scanf("%d",&c[i]);
    44     rep(i,1,n) rep(j,1,m) scanf("%I64d",&cost[i][j]);
    45     dp[0][1][0]=0;
    46     rep(i,0,n-1) rep(j,1,len) rep(k,0,m)
    47     {
    48         if (dp[i][j][k]!=INF)
    49         {
    50             if (c[i+1]==0)
    51             {
    52                 rep(col,1,m) if (col!=k)
    53                 {
    54                     if (k!=0) up(dp[i+1][j+1][col],dp[i][j][k]+cost[i+1][col]);
    55                     if (k==0) up(dp[i+1][j][col],dp[i][j][k]+cost[i+1][col]);
    56                 }
    57                 if (k!=0) up(dp[i+1][j][k],dp[i][j][k]+cost[i+1][k]);
    58             }
    59             else
    60             {
    61                 if (c[i+1]==k || k==0)
    62                 {
    63                     up(dp[i+1][j][c[i+1]],dp[i][j][k]);
    64                 }
    65                 if (c[i+1]!=k && k!=0)
    66                 {
    67                     up(dp[i+1][j+1][c[i+1]],dp[i][j][k]);
    68                 }
    69             }
    70         }            
    71     }
    72   /*  rep(i,0,n) rep(j,1,len) rep(k,0,m)
    73         if (dp[i][j][k]!=INF)
    74             printf("%d %d %d %I64d
    ",i,j,k,dp[i][j][k] );*/
    75     LL ans=INF;
    76     rep(k,1,m) up(ans,dp[n][len][k]);
    77     printf("%I64d
    ",ans==INF ?-1 :ans);
    78 }
    View Code

    Problem D Directed Roads

    题目大意

      有n个点,给定一个数组a[i](≠i),表示有一条i-->a[i]的有向边。

      可以将某些有向边的方向翻转,因此共有2^n的方案。

      问这些方案中有多少种方案使得所形成的图不含有环。

      n<=2*10^5

    解题分析

      由于一共只有n条边,整个图相当于被分成了若干个联通块,且每个联通块内有且只有一个环。

      若某个连通块中有i个点,存在一个点数为j的环,那么其对答案的贡献为2^(i-j) * (2^j-2)

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 200008            
    19 #define M 400008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 
    32 int n,num,huan;
    33 int a[N],mi[N+5],vis[N],len[N];
    34 struct line{
    35     int u,v,nt;
    36 }eg[M];
    37 int lt[N],sum;
    38 
    39 void add(int u,int v){
    40     eg[++sum]=(line){u,v,lt[u]};
    41     lt[u]=sum;
    42 }
    43 
    44 void dfs(int u,int fa)
    45 {
    46     vis[u]=1; len[u]=len[fa]+1; num++;
    47     for (int i=lt[u];i;i=eg[i].nt)
    48     {
    49         int v=eg[i].v;  
    50         if (vis[v]==0)
    51         {
    52             dfs(v,u);
    53         }
    54         else
    55         {
    56             if (v!=fa)
    57             {
    58                 huan=abs(len[u]-len[v])+1;
    59             }
    60         }
    61     }
    62 }
    63 
    64 int main(){
    65     mi[0]=1;
    66     rep(i,1,N) mi[i]=1ll*mi[i-1]*2 % mo;
    67     scanf("%d",&n);
    68     rep(i,1,n)
    69     {
    70         scanf("%d",&a[i]);
    71         add(i,a[i]);
    72         add(a[i],i);
    73     }
    74     clr(vis,0);
    75     LL ans=1;
    76     rep(i,1,n) if (vis[i]==0)
    77     {
    78         num=0; huan=0;
    79         dfs(i,0);
    80         if (num==2) huan=2;
    81         ans = (ans * (mi[huan]-2) % mo * mi[num-huan] % mo);
    82     }
    83     printf("%I64d
    ",ans);
    84 
    85 }
    View Code

    Problem E ZS and The Birthday Paradox

    题目大意

      假设一年有2^n天,问k个小朋友中有两个小朋友生日相同的概率。

      假设该概率约分后为 p / q ,输出p , q对1000003取模的解。

      n , k <= 10^18。

    解题分析

      若k > 2^n 则答案为1 / 1 , 否则答案为 1 - A(2^n,k) / (2^n)^k , 

      可以发现分子与分母的gcd必定为2^i。

      计算A(2^n,k)=(2^n) * (2^n-1) * ... * (2^n-k+1)含多少个因子2,相当于计算0~k-1以及2^n。

      求出gcd后,就可以暴力计算分子,分母对p取模后的结果,再乘上gcd的逆元。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000003;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 LL n,k,num;
    32 LL quick(LL x,LL y)
    33 {
    34     LL res=1;
    35     while (y)
    36     {
    37         if (y & 1) res = res*x % mo;
    38         x=x*x % mo;
    39         y>>=1;
    40     }
    41     return res;
    42 }
    43 int main(){
    44     scanf("%I64d%I64d",&n,&k);
    45     if (n<=60 && k>(1ll<<n)){
    46         printf("1 1
    ");
    47         return 0;
    48     }
    49     for (LL kk=k-1;kk;kk/=2) num+=kk/2;
    50     LL tmp=quick(2,n),ans=1;
    51     rep(i,1,k-1){
    52         ans = ans * (--tmp) % mo; 
    53         if (tmp==0) break;
    54     }
    55     ans=ans*quick(quick(2,mo-2),num) % mo;
    56     LL ans1=quick(quick(2,n),k-1);
    57     ans1=ans1*quick(quick(2,mo-2),num) % mo;
    58     ans=ans1-ans;
    59     if (ans<0) ans+=mo;
    60     printf("%I64d %I64d
    ",ans,ans1);
    61 
    62 }
    View Code
  • 相关阅读:
    从零开始学正则(四),什么是正则回溯?
    JS 正则表达式^$详解,脱字符^与美元符$同时写表示什么意思?
    从零开始学正则(三),理解正则的分组与反向引用
    从零开始学正则(二),如何用正则匹配特定位置?理解正则的锚,先行断言
    从零开始学正则(一),学习正则字符组,量词表示法与正则分支
    深入了解angularjs中的$digest与$apply方法,从区别聊到使用优化
    js 从两道面试题加深理解闭包与箭头函数中的this
    js 五种绑定彻底弄懂this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解
    【Spring深度分析】IoC/DI机制 配置文件式 基本实现
    BZOJ4311 向量(线段树分治+凸包)
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5821057.html
Copyright © 2011-2022 走看看