1. 程式人生 > >Codeforces Round #420 (Div. 2)

Codeforces Round #420 (Div. 2)

情況 ++ long long long sta roo logs 排序 queue

/******************************************************************************************************************

因為發現不敲題會變蠢...所以沒事還是做兩道題吧....

很久沒做過題然後發現C和E全都是因為沒用LL給卡住了...... 我真的是太蠢了

*******************************************************************************************************************/

A. Okabe and Future Gadget Laboratory

暴力判斷就行了

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 int Map[55][55];
 6 int main()
 7 {
 8     int n;
 9     scanf("%d",&n);
10     for(int i=1;i<=n;++i)
11         for(int j=1
;j<=n;++j) 12 scanf("%d",&Map[i][j]); 13 int Ans=1; 14 for(int i=1;i<=n;++i) 15 for(int j=1;j<=n;++j) 16 if(Map[i][j]!=1) 17 { 18 int flag=0; 19 for(int k=1;k<=n;++k) 20 if(k!=i&&!flag) 21 for(int q=1
;q<=n;++q) 22 if(q!=j&&Map[i][q]+Map[k][j]==Map[i][j]&&!flag) 23 flag=1; 24 if(!flag) 25 Ans=0; 26 } 27 printf("%s\n",Ans?"Yes":"No"); 28 return 0; 29 }

B. Okabe and Banana Trees

發現高度會很小,所以直接遍歷高度,然後就是一個等差數列求前綴和了

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 #define LL long long
 6 LL Sum[10000005]; 
 7 int main()
 8 {
 9     int m,b;
10     scanf("%d%d",&m,&b);
11     for(int i=1;i<=m*b;++i)
12     Sum[i]=Sum[i-1]+i;
13     LL Ans=0;
14     for(LL i=0;i<=b;++i)
15     {
16         LL x=m*(b-i);
17         LL tmp=0;
18         tmp+=(i+1)*Sum[x];
19         tmp+=(i*(i+1))*(x+1)/2;
20         Ans=max(Ans,tmp);
21     }
22     printf("%lld\n",Ans);
23     return 0;
24 }

C. Okabe and Boxes

這道題比較巧妙

暴力解法:(當然是不行滴

1.如果剛好能拿走就拿走

2.不能拿走我就排序

題目說肯定存在一個答案能滿足條件,就說明在第i次remove的時候i一定在序列裏

所以我們在remove的時候棧頂只有兩種情況

1.剛好是我們需要的

2.是我們不需要的值(這時候就直接排序

然後我們考慮之前說過的條件,remove時候i一定在序列裏,然後我們考慮把所有排過序的數字給標記一下(並不排序,只是標記一下

就有了第三種情況

3.遇到了我們標記過的值

這時候因為i一定在序列裏,然後考慮比i小的全都remove走了,所以如果遇到了標記的說明這時候直接把i拿走就好了,因為這時候棧裏面肯定全都是排好序的

然後我們就發現了棧的相對順序是不變的,所以每次排序我們只需要標記棧頂的那個元素

然後說是要取i,其實就是假裝i取取走了,其實還是在棧裏

總的來說就是當delete的時候

1.如果剛好能拿走就拿走

2.不能拿走我就標記一下棧頂(假裝排序

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 #define LL long long
 6 #define maxn 500005
 7 int stac[maxn];
 8 char str[15];
 9 int main()
10 {
11     int n;
12     int st=0,ed=0;
13     scanf("%d",&n);
14     int pos=0,Ans=0;
15     for(int i=1;i<=n*2;++i)
16     {
17         scanf("%s",str);
18         if(str[0]==a)
19         {
20             int x;
21             scanf("%d",&x);
22             stac[ed++]=x;
23         }
24         else
25         {
26             pos++;
27             if(stac[ed-1]==pos)
28             {
29                 ed--;
30                 continue;
31             }
32             else if(stac[ed-1]==0)
33             {
34                 continue;
35             }
36             else
37             {
38                 Ans++;
39                 stac[ed-1]=0;
40             }
41         }
42     }
43     printf("%d\n",Ans);
44     return 0;
45 }

D. Okabe and City

待補

E. Okabe and El Psy Kongroo

這道題第一眼遞推,然後發現k有點大.然後發現n特別小,所以就很明顯的按階段來跑矩陣快速冪

f[i+1][j]=f[i][j-1] + f[i][j] + f[i][j+1]然後判斷一下會不會溢出就好了,中間用個數組存放中間值,主要是害怕用到本來應該溢出的值

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<math.h>
  6 #include<queue>
  7 #include<stack>
  8 #include<string>
  9 #include<vector>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 #define lowbit(x) (x&(-x))
 14 typedef long long LL;
 15 const int maxn = 100005;
 16 const int inf=(1<<28)-1;
 17 #define Matrix_Size 20
 18 LL MOD=1000000007;
 19 int Size;
 20 struct Matrix
 21 {
 22     LL mat[Matrix_Size][Matrix_Size];
 23     void clear()
 24     {
 25         memset(mat,0,sizeof(mat));
 26     }
 27     void output()
 28     {
 29         for(int i = 0;i < Size;i++)
 30         {
 31             for(int j = 0;j < Size;j++)
 32                 printf("%d ",mat[i][j]);
 33             printf("\n");
 34         }
 35     }
 36     Matrix operator *(const Matrix &b)const
 37     {
 38         Matrix ret;
 39         for(int i = 0;i < Size;i++)
 40             for(int j = 0;j < Size;j++)
 41             {
 42                 ret.mat[i][j] = 0;
 43                 for(int k = 0;k < Size;k++)
 44                 {
 45                     long long tmp = (long long)mat[i][k]*b.mat[k][j]%MOD;
 46                     ret.mat[i][j] = (ret.mat[i][j]+tmp);
 47                     if(ret.mat[i][j]>=MOD)
 48                         ret.mat[i][j] -= MOD;
 49 
 50                 }
 51             }
 52         return ret;
 53     }
 54 };
 55 Matrix pow_M(Matrix a,long long n)
 56 {
 57     Matrix ret;
 58     ret.clear();
 59     for(int i = 0;i < Size;i++)
 60         ret.mat[i][i] = 1;
 61     Matrix tmp = a;
 62     while(n)
 63     {
 64         if(n&1)ret = ret*tmp;
 65         tmp = tmp*tmp;
 66         n>>=1;
 67     }
 68     return ret;
 69 }
 70 int S[17];
 71 int main()
 72 {
 73     Matrix A,B;
 74     S[0]=1;
 75     LL n,k;
 76     scanf("%lld%lld",&n,&k);
 77     for(int i=1;i<=n;++i)
 78     {
 79         LL st,ed,h;
 80         scanf("%lld%lld%lld",&st,&ed,&h);
 81         if(i==n)
 82             ed=k;
 83             
 84         Size=h+1;
 85         
 86         B.clear();
 87         for(int j=0;j<=h;++j)
 88         {
 89             B.mat[0][j]=S[j];
 90         }    
 91         
 92         A.clear();
 93         for(int j=0;j<=h;++j)
 94         {
 95             if(j>0)
 96                 A.mat[j-1][j]=1;
 97             A.mat[j][j]=1;
 98             if(j<h)
 99                 A.mat[j+1][j]=1;
100         }
101         
102         A=pow_M(A,ed-st);
103         B=B*A;
104         
105         for(int j=0;j<17;++j)
106             S[j]=0;
107         
108         for(int j=0;j<=h;++j)
109             S[j]=B.mat[0][j];
110         
111     }
112     printf("%d\n",B.mat[0][0]);
113     return 0;
114 } 

Codeforces Round #420 (Div. 2)