Codeforces Round #177 (Div. 2)
A: 求个和就行。
B:
题意:
给定一个n*m的矩阵,将每个方格内都有一个值。我们可以选择其中的任意一个方格执行+d 或者-d操作,问最终使得方格内的数全部相同的最小不数。
思路:
贪心,中位数
找最小值以及最大值,然后从最小值不断+d操作记录可能出现的数,知道大于最大值。然后查看一下所有矩阵中的数是否全部出现,如果全部出现,则说明一定可以得到一个所有值相同的矩阵。然后我们将所有值排序,取中位数,则中位数就是我们要得到的相等的那个值,然后计算每一个小方格到达该值的步数即可。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 107 #define N 107 using namespace std; const int inf = 0x7f7f7f7f; int a[N*N],la; bool vt[N*N]; int main() { // Read(); int n,m,d; int i,j; scanf("%d%d%d",&n,&m,&d); la = 0; CL(vt,false); int mi = inf; int ma = 0; for (i = 0; i < n; ++i) { for (j = 0; j < m; ++j) { scanf("%d",&a[la]); mi = min(a[la],mi); ma = max(a[la],ma); la++; } } i = mi; while (i <= ma) { vt[i] = true; i += d; } bool flag = false; for (i = 0; i < la; ++i) { if (!vt[a[i]]) { flag = true; break; } } if (flag) printf("-1\n"); else { sort(a,a + la); // for (i = 0; i < la; ++i) printf(">>%d\n",a[i]); int pos = 0; if (la%2 == 1) pos = la/2; else pos = la/2 - 1; int tmp = a[pos]; // printf("%d %d\n",pos,tmp); int ans = 0; for (i = 0; i < la; ++i) { ans += abs(a[i] - tmp)/d; } printf("%d\n",ans); } return 0; }
C:
题意:
给你一个长度为n的字符串,这些字符串由小写英文字母组成,要求长度为n的字符串里面必须包含有k个不通过的英文字母并且相邻两个字符不能相同,求满足上述条件的字典序最下的字符
串。
思路:
贪心:
见代码:
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 107 #define N 1000007 using namespace std; const int inf = 0x7f7f7f7f; char s[N]; int main() { // Read(); int n,m; int i,j; while (~scanf("%d%d",&n,&m)) { if (m > n) printf("-1\n");//m > n 肯定不行 else if (n == m)//相等 { for (i = 0; i < n; ++i) printf("%c",'a' + i); printf("\n"); } else// n > m { if (m == 1)//m == 1是不存在的 { printf("-1\n"); } else if (m == 2)// m == 2 ab是最小的 { int f = 0; for (i = 1; i <= n; ++i) { if (f == 0) { printf("a"); f = 1; } else { printf("b"); f = 0; } } printf("\n"); } else { int f = 0; for (i = 1; i <= n - (m - 2); ++i)//前一部分是ab { if (f == 0) { printf("a"); f = 1; } else { printf("b"); f = 0; } } //后一部分是不同的其他字符 for (i = 0; i < m - 2; ++i) printf("%c",'a' + i + 2); printf("\n"); } } } return 0; }
D:
题意:
给定两个数n,k,有n个房间,每个房间都一个以牌匾,上边标着下一个房间的房间号,房间号1-n。问满足:
1:从1 - k任意一件房间出发都能达到1的;
2:从k + 1 到 n 任意一间房间出发都不能到达1;
3:从1出发一定能够经过大于0的步数到达1;
存在多少种?
思路:
DFS+数学
对于小数据,我们一定敏感,k < min(8,n);
所以我们可以首先包搜出前k个的可能数,然后由于1,2的条件所以【1,k】与【k + 1,n】不会存在联系,而【k + 1,n】有(n - k)^(n - k)次方中可能,然后求成绩取余即可。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 107 #define N 10 using namespace std; const int inf = 0x7f7f7f7f; const int mod = 1000000007; int a[N]; int n,k; bool op[N]; ll ans; void dfs(int ct) { int i; if (ct == k) { for (i = 1; i <= k; ++i) { CL(op,false); op[1] = true; int p = a[i]; while (!op[p]) { op[p] = true; p = a[p]; } if (p == 1) continue; else break; } if (i > k) ans++; return ; } for (i = 1; i <= k; ++i) { a[ct + 1] = i; dfs(ct + 1); } } int main() { // Read(); // Write(); int i; while (~scanf("%d%d",&n,&k)) { ans = 0; for (i = 1; i <= k; ++i) { a[1] = i; dfs(1); } // cout<<">>>>>>"<<ans<<endl; for (i = k + 1; i <= n; ++i) { ans = ans*(n - k)%mod; } cout<<ans<<endl; } return 0; }
E:
题意:
输入n,求0-n的一个排列p0,p1 ...... pn,是的(0^p0) + (1^p1) + ......(n^pn)的值最大
思路:
贪心+位运算
我们只需要从最大的开始,找到他的二进制数的取反的数,然后让他们两个抑或即可取得最大值。
比赛的时候用了pow(2,i)来算2的i次幂,结果超时了,悲剧啊,以后还是尽量自己 写 pow2【】
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 107 #define N 1000007 using namespace std; const int inf = 0x7f7f7f7f; int a[N]; int pow2[22]; int b[22]; int main() { // Read(); // Write(); for (int i = 0; i <= 20; ++i) pow2[i] = (1<<i); int n; int i,j,k; scanf("%d",&n); CL(a,-1); int len = 0; for (k = n; k >= 0; --k) { if (a[k] != -1) continue; len = 0; int tmp = k; while (tmp) { b[len++] = tmp%2; tmp/=2; } // for (i = len - 1; i >= 0; --i) printf(">>%d\n",b[i]); int no = 0; j = 0; for (i = 0; i < len; ++i) { no = b[i]*pow2[j] + no; j++; } int nm = 0; j = 0; for (i = 0; i < len; ++i) { nm = (!b[i])*pow2[j] + nm; j++; } // printf("%d %d\n",no,nm); a[no] = nm; a[nm] = no; } ll ans = 0; for (i = 0; i <= n; ++i) { if (a[i] != -1) { ans += (i^a[i]); } else { ans += (i^i); a[i] = i; } } cout<<ans<<endl; for (i = 0; i <= n; ++i) printf("%d ",a[i]); return 0; }