Codeforces 339
这是一场5道题都写不到1K的CF。
A:
题意是排序。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5
6 using namespace std;
7
8 int n,z[100];
9
10 char s[100];
11
12 int main()
13 {
14 scanf("%s",s+1);
15 int l=strlen(s+1);
16 s[l+1]='+';
17 int p=1;
18 while (s[p]>='0' && s[p]<='9')
19 {
20 n++;
21 while (s[p]!='+')
22 z[n]=z[n]*10+s[p++]-'0';
23 p++;
24 }
25 sort(z+1,z+n+1);
26 for (int a=1;a<n;a++)
27 printf("%d+",z[a]);
28 printf("%d\n",z[n]);
29
30 return 0;
31 }
B:
一个环,顺时针一次走过给出来的N个点,问所需时间。
模拟。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4
5 using namespace std;
6
7 int n,m;
8
9 int main()
10 {
11 scanf("%d%d",&n,&m);
12 int p=1;
13 long long ans=0;
14 for (int a=1;a<=m;a++)
15 {
16 int pp;
17 scanf("%d",&pp);
18 if (pp>=p) ans+=pp-p;
19 else ans+=pp+n-p;
20 p=pp;
21 }
22 printf("%I64d\n",ans);
23
24 return 0;
25 }
C:
告诉你你有重量1-10的一些砝码,要求依次往左边和后边放砝码,要求每次放了之后被放的那边的重量都大于另外一边,给一种可行方案。
我一开始想多了想到构造去了,爆搜就行了。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4
5 using namespace std;
6
7 int m,ans[1010];
8
9 char s[12];
10
11 bool dfs(int n,int d)
12 {
13 if (n>m)
14 {
15 printf("YES\n");
16 for (int a=1;a<=m;a++)
17 printf("%d ",ans[a]);
18 printf("\n");
19 return true;
20 }
21 for (ans[n]=1;ans[n]<=10;ans[n]++)
22 if (s[ans[n]]=='1' && d+ans[n]>0 && ans[n]!=ans[n-1] && dfs(n+1,-d-ans[n])) return true;
23 return false;
24 }
25
26 int main()
27 {
28 scanf("%s",s+1);
29 scanf("%d",&m);
30 if (!dfs(1,0)) printf("NO\n");
31
32 return 0;
33 }
D:
2^n个数,奇数次把第一个和第二个、第三个和第四个……做或运算得到只剩一半的数,偶数次则做异或运算,有修改操作,问每次修改之后最后会得到的数是多少。
最基础的线段树。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4
5 using namespace std;
6
7 #define lson d-1,l,m,rt<<1
8 #define rson d-1,m+1,r,rt<<1|1
9
10 const int maxn=(1<<17)+20;
11
12 int n,m,z[maxn<<2|1];
13
14 void build(int d,int l,int r,int rt)
15 {
16 if (l==r)
17 {
18 scanf("%d",&z[rt]);
19 return;
20 }
21 int m=(l+r)>>1;
22 build(lson);
23 build(rson);
24 if (d&1) z[rt]=z[rt<<1]|z[rt<<1|1];
25 else z[rt]=z[rt<<1]^z[rt<<1|1];
26 }
27
28 void modify(int d,int l,int r,int rt,int p,int v)
29 {
30 if (l==r)
31 {
32 z[rt]=v;
33 return;
34 }
35 int m=(l+r)>>1;
36 if (p<=m) modify(lson,p,v);
37 else modify(rson,p,v);
38 if (d&1) z[rt]=z[rt<<1]|z[rt<<1|1];
39 else z[rt]=z[rt<<1]^z[rt<<1|1];
40 }
41
42 int main()
43 {
44 scanf("%d%d",&n,&m);
45 build(n,1,1<<n,1);
46 for (int a=1;a<=m;a++)
47 {
48 int p,v;
49 scanf("%d%d",&p,&v);
50 modify(n,1,1<<n,1,p,v);
51 printf("%d\n",z[1]);
52 }
53
54 return 0;
55 }
E:
1-n的排列,给出对其中某些段做了k次翻转操作的序列,问这次k次的操作序列。
考虑从最左边找到的第一个不符合位置的数我们只需要将它到它对应的数所在的位置进行翻转即可满足该数,对这个过程进行搜索直到找到解即可。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5
6 using namespace std;
7
8 int n,z[1010],l[4],r[4];
9
10 bool check()
11 {
12 for (int a=1;a<=n;a++)
13 if (z[a]!=a) return false;
14 return true;
15 }
16
17 bool dfs(int x)
18 {
19 if (check())
20 {
21 printf("%d\n",x-1);
22 for (int a=x-1;a>0;a--)
23 printf("%d %d\n",l[a],r[a]);
24 return true;
25 }
26 if (x>3) return false;
27 for (int a=1;a<=n;a++)
28 if (z[a]!=a)
29 {
30 l[x]=a;
31 for (int b=a+1;;b++)
32 if (z[b]==a)
33 {
34 r[x]=b;
35 reverse(z+a,z+b+1);
36 if (dfs(x+1)) return true;
37 reverse(z+a,z+b+1);
38 break;
39 }
40 break;
41 }
42 for (int a=n;a>=1;a--)
43 if (z[a]!=a)
44 {
45 r[x]=a;
46 for (int b=a-1;;b--)
47 if (z[b]==a)
48 {
49 l[x]=b;
50 reverse(z+b,z+a+1);
51 if (dfs(x+1)) return true;
52 reverse(z+b,z+a+1);
53 break;
54 }
55 break;
56 }
57 return false;
58 }
59
60 int main()
61 {
62 scanf("%d",&n);
63 for (int a=1;a<=n;a++)
64 scanf("%d",&z[a]);
65 dfs(1);
66
67 return 0;
68 }