Codeforces Round #206 (Div. 2)
A:
题意:
给你两个数k,d,k表示有多少位数, d表示不断的对一个数的个数为求和,最后的得到的0-9的数
思路:
if (k == 1) 直接输出d,
if (k != 1) if (d == 0) 非法 else 输入d *10^(k - 1)
int main() { int k,d; scanf("%d%d",&k,&d); if (k == 1) printf("%d\n",d); else { if (d == 0) printf("No solution\n"); else { string ans = "1"; for (int i = 1; i < k - 1; ++i) ans += "0"; ans += (d - 1) + '0'; cout << ans << endl; } } return 0; }
B:
题意:
有两种交通工具非别为n个bus,m个trolleys 。我们有四种票可以选择c1,c2,c3,c4分别描述如下
-
A ticket for one ride on some bus or trolley. It costs c1 burles;
-
A ticket for an unlimited number of rides on some bus or on some trolley. It costs c2 burles;
-
A ticket for an unlimited number of rides on all buses or all trolleys. It costs c3 burles;
-
A ticket for an unlimited number of rides on all buses and trolleys. It costs c4 burles.
给出每种交通工具使用的次数a[] 表示对应的bus使用的次数, b[]表示trolleys 使用的次数,问如何选票是的最后费用最少。
思路:
首先一个c4和2个c3是确定的,然后我们再看有一个c3的话,然后对另一中交通工具进行c1和c2的选择,然后我们计算a[i](/b[i])用c1省还是用c2省就可以了。 如果只有c1,c2的话同样计算。
#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 long long #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 5007 #define N 1007 using namespace std; const ll mod = 1000000009; const ll inf = (1LL<<53); int c1,c2,c3,c4; int a[N],b[N]; int n,m; int main() { scanf("%d%d%d%d",&c1,&c2,&c3,&c4); scanf("%d%d",&n,&m); for (int i = 0; i < n; ++i) scanf("%d",&a[i]); for (int i = 0; i < m; ++i) scanf("%d",&b[i]); int ans = min(c4,2*c3); //1c3 int s = c3; for (int i = 0; i < n; ++i) { int v1 = c1*a[i]; int v2 = c2; s += min(v1,v2); if (s > ans) break; } ans = min(ans, s); s = c3; for (int i = 0; i < m; ++i) { int v1 = c1*b[i]; int v2 = c2; s += min(v1,v2); if (s > ans) break; } ans = min(ans, s); s = 0; for (int i = 0; i < n; ++i) { int v1 = c1*a[i]; int v2 = c2; s += min(v1,v2); if (s > ans) break; } for (int i = 0; i < m; ++i) { int v1 = c1*b[i]; int v2 = c2; s += min(v1,v2); if (s > ans) break; } ans = min(ans, s); printf("%d\n",ans); return 0; }
C:
题意:
给你n个数a[],我们可以从左边取,也可以从右边取数。从左边取一个数的的代价为a[i]*L,如果连续从左边取得花,每次还要加上一个QL, 从右边取同左边取得操作一样 R,QR。问如何去才能取得最小值?
思路:
不论如何取,总会有一个结束的点我们枚举结束的点,然后计算左边取了多少个,右边取了多少个,然后哪边多,哪边就加上多出那部分*Qx, x{L,R}即可
#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 long long #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 5007 #define N 100007 using namespace std; const ll mod = 1000000009; const int inf = 0x7fffffff; int n,l,r,Ql,Qr; int w[N]; int sumL[N],sumR[N]; int main() { scanf("%d%d%d%d%d",&n,&l,&r,&Ql,&Qr); for (int i = 1; i <= n; ++i) scanf("%d",&w[i]); sumL[0] = 0; for (int i = 1; i <= n; ++i) sumL[i] = sumL[i - 1] + w[i]*l; sumR[0] = 0; for (int i = n, j = 1; i >= 1 && j <= n; --i,j++) sumR[j] = sumR[j - 1] + w[i]*r; // for (int i = 1; i <= n; ++i) printf("%d ",sumL[i]); // printf("\n"); // for (int i = 1; i <= n; ++i) printf("%d ",sumR[i]); // printf("\n"); int ans = min(sumL[n] + (n - 1)*Ql, sumR[n] + (n - 1)*Qr); for (int i = 1; i <= n - 1; ++i) { int x,y; x = i; y = n - i; if (x > y) { int tmp = sumL[x] + (x - y - 1)*Ql + sumR[y]; ans = min(ans, tmp); } else if (x == y){ int tmp = sumL[x] + sumR[y]; ans = min(ans, tmp); } else { int tmp =sumR[y] + (y - x - 1)*Qr + sumL[x]; // printf("%d %d\n",i,tmp); ans = min(ans, tmp); } } printf("%d\n",ans); return 0; }
D:
题意:
给你一个n*n的只含有英文小写字母的矩阵,然后我们从s[0][0]出发到目的地s[n - 1][n - 1]规定只能向下,向右走。每条路径对应了一个字符串,如果该字符串含有a的数量大于b的数量,1赢,anum == bnum 平局, anum < bnum 2赢。 他们轮流选择下一步该走哪一个。问最后谁赢?
思路:
首先1如果选择的话,肯定是选择a比较多的路线; 2如果选择的话肯定的a少b多的路线。 然后dp一下就好了。
By E_star, contest: Codeforces Round #206 (Div. 2), problem: (D) Game with Strings, Accepted, # //#pragma comment(linker, "/STACK:1024000000,1024000000") #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 long long #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 keyTree (chd[chd[root][1]][0]) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 100007 #define N 100007 using namespace std; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; const int inf = 0x7f7f7f7f; const int mod = 1000000007; const double eps = 1e-8; const int R = 100007; char s[22][22]; int n; int dp[42][1<<20]; int a[42][26]; int ans; int DP(int step,int state) { if (dp[step][state] != 1e9) return dp[step][state]; int add = 0; for (int i = 0; i < n; ++i) { if (state & (1<<i)) { if (s[i][step - i] == 'a') add++; else if (s[i][step - i] == 'b') add--; break; } } if (step == 2*n - 2) return dp[step][state] = add; if (step % 2 == 0) { for (int i = 0; i < 26; ++i) { int next = a[step + 1][i] & (state | (state << 1)); if (next == 0) continue; dp[step][state] = min(dp[step][state], DP(step + 1, next) + add); } } else { dp[step][state] = -1e9; for (int i = 0; i < 26; ++i) { int next = a[step + 1][i] & (state | (state << 1)); if (next == 0) continue; dp[step][state] = max(dp[step][state], DP(step + 1, next) + add); } } return dp[step][state]; } int main() { scanf("%d",&n); for (int i = 0; i < n; ++i) scanf("%s", s[i]); CL(a,0); for (int i = 0; i < 2*n - 1; ++i) { for (int j = 0; j < n; ++j) { if (i - j < 0 || i - j >= n) continue; a[i][s[j][i - j] - 'a'] |= (1<<j); } } for (int i = 0; i < 2*n - 1; ++i) for (int j = 0; j < (1<<20); ++j) dp[i][j] = 1e9; int ans = DP(0,1); if (ans == 0) printf("DRAW\n"); else if (ans > 0) printf("FIRST\n"); else printf("SECOND\n"); return 0; }
E:
#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 keyTree (chd[chd[root][1]][0]) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 100007 #define N 300007 using namespace std; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; const double inf = 100000000000.0; const int mod = 1000000007; int n,k; int a[N]; int main() { scanf("%d%d",&n,&k); for (int i = 0; i < n; ++i) scanf("%d",&a[i]); sort(a, a + n); if (a[0] <= k) { printf("%d\n",a[0]); } else { int ans = a[0]; while (1) { int i; for (i = 0; i < n; ++i) { if (a[i]%ans > k) { while (a[i]%ans > k) ans--; break; } } if (i == n) break; } printf("%d\n",ans); } return 0; }