第十六周 12.14---12.20

新的一周>_<

---12.14

补之前的一场 cf

cf 604c

http://codeforces.com/contest/604/problem/C

给一串长度为 n 的 01串,可以翻转一个区间,问能够得到的最长的01序列是多长(可以不连续)

没有想出来,,,

其实可以发现,翻转一个区间,能够给原串带来2个贡献,所以算出原来的最长的加上 2 和 n 取最小值就好了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 const int maxn = 1e5+5;
 9 char s[maxn];
10 int n;
11 
12 void solve(){
13     int c = 0;
14     for(int i = 1;i <= n;){
15         c++;
16         int j = i;
17         while(j <= n && s[i] == s[j]) j++;
18         i = j;
19     }
20     int ans = 0;
21     ans = min(c+2,n);
22     printf("%d\n",ans);
23 }
24 
25 int main(){
26     while(scanf("%d",&n) != EOF){
27         scanf("%s",s+1);
28         solve();
29     }
30     return 0;
31 }
View Code

 

 ---12.15

cf 318 c

http://codeforces.com/problemset/problem/318/C

给出两个数 x,y ,再给出一个 m ,每次操作可以用 x+y 去替换掉 x , y 中的一个更小的数,

问至少需要多少次操作,使得这两个数中至少有一个大于等于m

一开始就是想的,用 x+y 去代替(x,y) 里面的更小的,然后一直while循环到大于等于m

然后又wa又t的- -

是漏掉了 x < 0 && y > 0,这种应该先直接算出 x 需要多少次变成正的

然后还t了,,,是因为计数那个cnt也会爆int

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<vector>
 7 using namespace std;
 8 
 9 typedef long long LL;
10 const int maxn = 1e6+5;
11 LL a[maxn];
12 LL x,y,m;
13 
14 void solve(){
15    if(x >= m || y >= m){
16     puts("0");
17     return;
18    }
19    if(x < m && y < m && x <= 0 && y <= 0){
20     puts("-1");
21     return;
22    }
23    if(x > y) swap(x,y);
24    LL dayu0;
25    int flag = 0;
26    if(x < 0 && y > 0){
27         int ret = 0;
28         dayu0 = (-x)/y;
29         if((-x)%y) dayu0++;
30         x = x + 1LL*dayu0*y;
31       //  printf("x = %I64d   dayu0 = %I64d\n",x,dayu0);
32        flag = 1;
33    }
34    LL c = y;
35    LL cnt = 0;
36    while(c < m){
37     c = x+y;
38     x = y;
39     y = c;
40     if(x > y) swap(x,y);
41     cnt++;
42    }
43    if(flag) printf("%I64d\n",cnt+dayu0);
44    else printf("%I64d\n",cnt);
45 }
46 
47 int main(){
48     while(scanf("%I64d %I64d %I64d",&x,&y,&m) != EOF){
49         solve();
50     }
51     return 0;
52 }
View Code

 

补个bc

hdu 5596 GTW likes gt

比赛的时候用树状数组写的,,,一直调不对,,,后来又想不通这个做法了,,,

看的题解的O(n) 的做法写的

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 const int maxn = 5e5+5;
 9 int a[maxn],b[maxn],c[maxn];
10 int cnt[maxn];
11 int n,m;
12 
13 void solve(){
14     int mx0 = -1,mx1 = -1;
15     int l = 0;
16     for(int i = n;i >= 1;i--){
17             if(cnt[i]) {
18                 mx1 -= cnt[i];
19                 mx0 -= cnt[i];
20             }
21             if(a[i] == 0){
22                 if(mx1 >= b[i]) l++;
23                 mx0 = max(mx0,b[i]);
24             }
25             else{
26                 if(mx0 >= b[i]) l++;
27                 mx1 = max(mx1,b[i]);
28             }
29     }
30     printf("%d\n",n-l);
31 }
32 
33 int main(){
34     int T;
35     scanf("%d",&T);
36     while(T--){
37         scanf("%d %d",&n,&m);
38         memset(cnt,0,sizeof(cnt));
39         for(int i = 1;i <= n;i++) scanf("%d %d",&a[i],&b[i]);
40         for(int i = 1;i <= m;i++) {
41             scanf("%d",&c[i]);
42             cnt[c[i]]++;
43         }
44         solve();
45     }
46     return 0;
47 }
View Code

 

今天焊成了 “趣味闪灯”,,,不过不知道通电之后会不会闪阿,,,好惶恐---

 

---12.16

hdu 5597 GTW likes function

题解说的打表,,,

证明还没有看---

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 typedef long long LL;
 9 LL n,x;
10 
11 LL euler(LL v){
12     LL k = sqrt(1.0*v);
13     LL res = v;
14     for(LL i = 2;i <= k;i++) if(v%i == 0){
15         while(v%i == 0) v /= i;
16         res = res/i*(i-1);
17     }
18     if(v > 1) res = res/v*(v-1);
19     return res;
20 }
21 
22 int main(){
23     while(scanf("%I64d %I64d",&n,&x) != EOF){
24         printf("%I64d\n",euler(n+x+1));
25     }
26     return 0;
27 }
View Code

 

---12.17

补个cf 335 div2

这场 cf 打得太挫----默默跌绿---

cf 606 a

http://codeforces.com/contest/606/problem/A

感觉自己想复杂了,而且因为自己是乘以 2来算的,

一直 wa 8

因为是 两个相同颜色的可以换一个别的颜色的,所以应该直接除以2来算

贴一下代码,,纪念下自己的sb - -

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<vector>
  5 using namespace std;
  6 
  7 typedef long long LL;
  8 const int maxn = 1e6+5;
  9 int n,m;
 10 int a,x[15],used[15];
 11 int b,c;
 12 
 13 void solve(){
 14   if(a < x[1] && b < x[2] && c < x[3]){
 15     puts("No");
 16     return;
 17   }
 18   if(a >= x[1] && b >= x[2] && c >= x[3]){
 19     puts("Yes");
 20     return;
 21   }
 22 
 23   int cnt = 0;
 24   if(a < x[1]){
 25         int need = x[1]-a;
 26         //need = need;
 27         int cb = (x[2]-b)/2;
 28         int cc = (x[3]-c)/2;
 29         cb = -cb,cc = -cc;
 30         if(cb >= need){
 31             cnt++;
 32             b-= need*2;
 33         }
 34         else if(cc >= need){
 35             cnt++;
 36             c-= need*2;
 37         }
 38         else if((cb + cc) >= need){
 39                 cnt++;
 40                 int t = b-x[2];
 41                 b = x[2];
 42                 c -= (need*2-t);
 43         }
 44         else{
 45             puts("No");
 46             return;
 47         }
 48   }
 49   else cnt++;
 50 
 51    if(b < x[2]){
 52         int need = x[2]-b;
 53       //  need = need;
 54         int ca = (x[1]-a)/2;
 55         int cc = (x[3]-c)/2;
 56         ca = -ca,cc = -cc;
 57       //  printf("ca = %d  cc = %d\n",ca,cc);
 58         if(ca >= need){
 59             cnt++;
 60             a-= need*2;
 61         }
 62         else if(cc >= need){
 63             cnt++;
 64             c-= need*2;
 65         }
 66         else if((ca + cc) >= need){
 67                 cnt++;
 68                 int t = x[1]-a;t = -t;
 69                 a = x[1];
 70                 c -= (need*2-t);
 71         }
 72         else{
 73             puts("No");
 74             return;
 75         }
 76   }
 77   else cnt++;
 78 
 79  // printf("a = %d  b = %d  c = %d\n",a,b,c);
 80 
 81    if(c < x[3]){
 82         int need = x[3]-c;
 83        // need = need*2;
 84         int ca = (x[1]-a)/2;
 85         int cb = (x[2]-b)/2;
 86         ca = -ca,cb = -cb;
 87     //    printf("ca = %d  cb = %d\n",ca,cb);
 88         if(ca >= need){
 89             cnt++;
 90             a-= need*2;
 91         }
 92         else if(cb >= need){
 93             cnt++;
 94             b-= need*2;
 95         }
 96         else if((ca + cb) >= need){
 97                 cnt++;
 98                 int t = x[1]-a;t=-t;
 99                 a = x[1];
100                 b -= (2*need-t);
101         }
102         else{
103             puts("No");
104             return;
105         }
106   }
107   else cnt++;
108   if(cnt == 3) puts("Yes");
109   else puts("No");
110 
111 }
112 
113 int main(){
114     while(scanf("%d %d %d",&a,&b,&c) != EOF){
115         scanf("%d %d %d",&x[1],&x[2],&x[3]);
116 //        b = a[2],c = a[3];
117         solve();
118     }
119     return 0;
120 }
View Code

 

 

 

cf 606 b

比赛的时候看过的人少,没有看- -

读懂题就好了

 

cf 606 c

sb 地想都没想 直接 n-LIS   结果居然过了初测---

应该是 dp[i] 表示以 i 结尾 的最长的连续的序列的长度

然后是 n - max(dp[i])

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstring>
 6 using namespace std;
 7 
 8 const int maxn = 1e6+5;
 9 int a[maxn],dp[maxn],n;
10 
11 void solve(){
12     memset(dp,0,sizeof(dp));
13     dp[a[1]] = 1;
14     for(int i = 2;i <= n;i++){
15         dp[a[i]] = dp[a[i]-1]+1;
16    //     printf("dp[%d] = %d\n",a[i],dp[a[i]]);
17     }
18     int ans = 0;
19     for(int i = 1;i <= n;i++) ans = max(ans,dp[i]);
20     printf("%d\n",n-ans);
21 }
22 
23 int main(){
24     while(scanf("%d",&n) != EOF){
25         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
26         solve();
27     }
28     return 0;
29 }
View Code

 

 

cf 606 d

构造一棵菊花树,然后依次向上面加图边

加边的顺序搞不清楚,wa 到死

后来问了一神

因为构造树 的时候 加边 是

1--2,1--3,1--4,---,1--n;这样

然后加图边的时候,如果是

2--3,2--4,2--5,---,2--n

那么在 加 1-- n 这条边之前,就已经加了 2-- n这条边了

2--n 这条边 比 1--n 这条边 短

这样,就应该选择 2--n这条边,而不是构造的 1--n那条边,就不行了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<vector>
 7 using namespace std;
 8 
 9 typedef long long LL;
10 const int maxn = 1e6+5;
11 int n,m;
12 struct Edge{
13     int a,b;
14     int id;
15 }e[2*maxn];
16 int vis1[maxn];
17 int vis2[maxn];
18 
19 Edge ans[2*maxn];
20 
21 int cmp(Edge n1,Edge n2){
22     if(n1.a != n2.a) return n1.a < n2.a;
23     return n1.b > n2.b;
24 }
25 
26 int cmp1(Edge n1,Edge n2){
27     return n1.id < n2.id;
28 }
29 
30 void solve(){
31     memset(vis1,0,sizeof(vis1));
32     memset(vis2,0,sizeof(vis2));
33     int shul = 1,shur = 1;
34     int tul = 2,tur = 2;
35     int u,v;
36     sort(e+1,e+m+1,cmp);
37 
38   /*  printf("---begin---\n");
39     for(int i = 1;i <= m;i++){
40         printf("---%d %d\n",e[i].a,e[i].b);
41     }
42     printf("---end---\n");*/
43     LL c1 = 0,c2 = 0;
44     for(int i = 1;i <= m;i++){
45         if(e[i].b == 1){
46             u = 1;
47             shul++;
48             v = shul;
49             c1++;
50             ans[i].a = u;ans[i].b = v;ans[i].id = e[i].id;
51         }
52         else c2++;
53         if(c1*(c1-1)/2 < c2){
54             puts("-1");
55             return;
56         }
57     }
58 
59   /*  for(int i = 1;i <= m;i++){
60         printf("ans[%d].a = %d  ans[%d].b = %d  \n",i,ans[i].a,i,ans[i].b);
61     }*/
62 
63     int cnt = 1;
64    // printf("shul = %d\n",shul);
65     for(int i = 3;i <= shul;i++){
66             if(cnt > m) break;
67         for(int j = 2;j < i;j++){
68           //  printf("----i = %d  j = %d  cnt = %d\n",i,j,cnt);
69             while(e[cnt].b) cnt++;
70             ans[cnt].a = i;
71             ans[cnt].b = j;
72             ans[cnt].id = e[cnt].id;
73             cnt++;
74           //  printf("---i = %d  j = %d  cnt = %d\n",i,j,cnt);
75           //  break;
76         }
77     }
78 
79     sort(ans+1,ans+m+1,cmp1);
80     for(int i = 1;i <= m;i++){
81         printf("%d %d\n",ans[i].a,ans[i].b);
82     }
83 }
84 
85 int main(){
86     while(scanf("%d %d",&n,&m) != EOF){
87         for(int i = 1;i <= m;i++){
88             scanf("%d %d",&e[i].a,&e[i].b);
89             e[i].id = i;
90         }
91         solve();
92     }
93     return 0;
94 }
View Code

 

---12.18

cf 305 c

http://codeforces.com/problemset/problem/305/C

给出 n 个数,a1,a2,a3,---,an

问至少加入几个数,b1,b2,---,bm

使得 2^a1 + 2^a2 + --- + 2^an + 2^b1 + 2^b2 + --- + 2^bm 的和为 2 ^v -1(v为一个整数)

 

因为 是 2^v-1的话,转化成二进制,它的每一位都是 1

然后最开始的想法是,统计每一个相同的ai 的个数,换成 尽可能多的数

然后就看从 0 1 2 到 最大的那个数中间少几个,就加几个

可是是错的,,不知道为什么是错的--

 

然后,就像貌似是10月份的一场cf的一题那样,

如果队列里面取出 的 x ,y

x == y,就进位 x+1放进去

x != y,不进位,再把y放进去

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 using namespace std;
 8 
 9 const int maxn = 1e5+5;
10 int a[maxn],n;
11 
12 void solve(){
13     priority_queue<int,vector<int> ,greater<int> > q;
14     for(int i = 1;i <= n;i++) q.push(a[i]);
15     int ed = -1;
16     int x,y;
17     vector<int> c;
18     while(!q.empty()){
19         x = q.top();q.pop();
20         ed = max(ed,x);
21         if(q.empty()) {
22             c.push_back(x);
23             break;
24         }
25         y = q.top();q.pop();
26         ed = max(ed,y);
27         if(x != y) {
28             c.push_back(x);
29             q.push(y);
30         }
31         else q.push(x+1);
32     }
33    // printf("ed = %d\n",ed);
34     printf("%d\n",ed+1-c.size());
35 }
36 
37 int main(){
38     while(scanf("%d",&n) != EOF){
39         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
40         solve();
41     }
42     return 0;
43 }
View Code

 

---12.19

做了第一次  cf 的educational round

 

---12.20

cf 304 c

http://codeforces.com/problemset/problem/304/C

给出 n,然后构造三个序列 a,b,c

使得对于任意 的 (a[i] + b[i])% n == (c[i] %  n)

打表找规律

发现偶数构造不出来,奇数按照

0 2 4 --- 1 3 ---

0 n-1 n-2 --- 2 1这样来放

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1e5+5;
 8 int a[maxn],b[maxn],c[maxn];
 9 int n;
10 
11 void solve(){
12     if(n%2 == 0){
13         puts("-1");
14         return;
15     }
16     for(int i = 0;i < n;i++) c[i] = i;
17     a[0] = 0;
18     for(int i = 1;i <= n/2;i++){
19         a[i] = i*2;
20         a[i+n/2] = i*2-1;
21     }
22     b[0] = 0;
23     for(int i = 1;i < n;i++){
24         b[i] = n-i;
25     }
26     for(int i = 0;i < n;i++) printf("%d ",a[i]);
27     printf("\n");
28     for(int i = 0;i < n;i++) printf("%d ",b[i]);
29     printf("\n");
30     for(int i = 0;i < n;i++) printf("%d ",c[i]);
31     printf("\n");
32 }
33 
34 int main(){
35     while(scanf("%d",&n) != EOF){
36         solve();
37     }
38     return 0;
39 }
View Code

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/5044062.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值