Codeforces Round #221 (Div. 2)
A. Lever
题意:给出下面这种字符串,^是杠杆的支点,问杠杆是否平衡。
9===^==1
分析:直接做。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; char s[1000005]; int main(){ long long i, j, k; long long l, r; while (scanf("%s",s)!=EOF){ long long g = 0; l = r = 0; for (i=0; s[i]; i++){ if (s[i] == '^') break; } g = i; for (i=g-1; i>=0; i--){ if (s[i]=='=')continue; l += (g-i)*(long long)(s[i]-'0'); } for (i=g+1; s[i]; i++){ if (s[i]=='=')continue; r += (i-g)*(long long)(s[i]-'0'); } if (l > r)printf("left\n"); else if (r > l)printf("right\n"); else printf("balance\n"); } return 0; }
B. I.O.U.
题意:给出每个关系,a, b, c表示a欠b c元,问通过调整,最后总的欠债数的和最少是多少,
例如:
1 2 20
2 3 20
总的欠债额是40,调整之后,1欠3 20元,2谁都不欠。
分析:假设每个人被欠的钱都被还了,那么他再拿这个钱去还他欠的钱即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 102; int g[maxn][maxn]; int ma[maxn]; int n, m; int main(){ while (scanf("%d %d",&n,&m)!=EOF){ memset(g, 0, sizeof(g)); memset(ma, 0, sizeof(ma)); int a, b, c; while (m--){ scanf("%d %d %d",&a,&b,&c); g[a][b] = c; ma[b] += c; } for (int i=1; i<=n; i++){ for (int j=1; j<=n; j++){ if (g[i][j]){ if (ma[i] >= g[i][j]){ ma[i] -= g[i][j]; } else{ ma[i] = 0; break; } } } } int res = 0; for (int i=1; i<=n; i++){ res += ma[i]; } printf("%d\n",res); } return 0; }
题意:一个长度大于3的字符串,里面一定含有1,6,8,9,把这个字符串调整一下使得最后的数可以被7整除。
分析:构造。可以把1,6,8,9放到字符串最前面,它的全排列对7的余数覆盖了1,2,3,4,5,6,只要枚举一下全排列即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/**************************************** * File Name: 221c.cpp * Author: sky0917 * Created Time: 2013年12月25日 7:24:58 ****************************************/ #include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000005; int p[4] = {1, 6, 8, 9}; int n; char s[maxn]; int main(){ int i, j, k; while (scanf("%s",s)!=EOF){ n = strlen(s); for (j=0; j<4; j++){ for (i=0; i<n; i++){ if (s[i] == p[j]+'0'){ swap(s[i], s[n-j-1]); } } } s[n-4] = '\0'; j = 0; k = 1; for (i=0; i<n-4; i++){ j = (j*10 + s[i]-'0') % 7; k = (k*10) % 7; } j = (7-j) % 7; bool flag = false; while (1){ int val = 0; for (i=0; i<4; i++){ val = (val * 10 + p[i]) % 7; } val = (val * k) % 7; if (val == j){ for (i=0; i<4; i++) printf("%d",p[i]); printf("%s\n",s); flag = true; break; } if (!next_permutation(p, p+4)) break; } if (!flag)printf("0\n"); } return 0; }
题意:一个n*m的grid,里面的数字只有1,0,你可以任意调换两行的顺序,问调换之后的方格阵中满足所有元素都是1的矩阵的面积最大是多少。
分析:枚举子矩阵的列的起点,然后计算出g[i][j],他表示从(i,j)向右连续的1的个数,用f[j]保存,对其从大到小排序,然后枚举f[j]*row,找出最大值,时间复杂度m*n*log(n) --!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/**************************************** * File Name: 221d.cpp * Author: sky0917 * Created Time: 2013年12月25日 6:59:33 ****************************************/ #include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 5002; char a[maxn][maxn]; int la[maxn][maxn]; int f[maxn]; int n, m; void solve(){ for (int i=1; i<=n; i++){ la[i][0] = 0; for (int j=1; j<=m; j++){ if (a[i][j] == '1'){ la[i][j] = la[i][j-1] + 1; } else la[i][j] = 0; } } int res = 0; for (int j=1; j<=m; j++){ for (int i=1; i<=n; i++){ f[i] = la[i][j]; } sort(f+1, f+n+1); for (int i = n; i>0; i--){ res = max(res, (n-i+1)*f[i]); } } printf("%d\n",res); } int main(){ while (scanf("%d %d",&n,&m)!=EOF){ for (int i=1; i<=n; i++){ scanf("%s",a[i]+1); } solve(); } return 0; }