Section 2.1
The Castle:
/*
ID: beihai2013
TASK: castle
LANG: C++
*/
/*
简单搜索凑出所有连通快,四进制表示四个方向也是写的很熟练的那种了
值得注意的是farthest是最靠近的意思
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50 + 5;
int g[MAXN][MAXN];
int sccno[MAXN][MAXN], scccnt, num[MAXN];
int n, m;
int dx[] = {0, -1, 0, 1};
int dy[] = {-1, 0, 1, 0};
bool validPos(int x, int y){if(x >= 0 && x < n && y >= 0 && y < m) return true; else return false;}
void dfs(int x, int y)
{
sccno[x][y] = scccnt;
num[scccnt]++;
for(int i = 0 ; i < 4 ; i++) {
if((1 << i) & g[x][y]) continue;
int tx = dx[i] + x, ty = dy[i] + y;
if(!validPos(tx, ty)) continue;
if(sccno[tx][ty] == 0) dfs(tx, ty);
}
}
int main()
{
freopen("castle.in", "r", stdin);
freopen("castle.out", "w", stdout);
while(scanf("%d%d",&m, &n) != EOF) {
for(int i = 0 ; i < n ; i++) for(int j = 0 ; j < m ; j++) scanf("%d", &g[i][j]);
memset(sccno, 0, sizeof sccno);
scccnt = 0;
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < m ; j++) {
if(sccno[i][j] == 0) {
num[++scccnt] = 0;
dfs(i, j);
}
}
}
// for(int i = 0 ; i < n ; i++) {
// for(int j = 0 ; j < m ; j++) printf("%d ", sccno[i][j]);
// printf("\n");
// }
// system("pause");
printf("%d\n", scccnt);
int res1 = 0, res2 = 0;
int resx, resy, dir;
for(int y = 0 ; y < m ; y++) {
for(int x = n - 1 ; x >= 0 ; x--) {
res1 = max(res1, num[sccno[x][y]]);
for(int k = 1 ; k < 3 ; k++) {
int tx = x + dx[k];
int ty = y + dy[k];
if(validPos(tx, ty) && sccno[x][y] != sccno[tx][ty]) {
if(res2 < num[sccno[x][y]] + num[sccno[tx][ty]]) {
res2 = num[sccno[x][y]] + num[sccno[tx][ty]];
resx = x, resy = y;
dir = k;
}
}
}
}
}
printf("%d\n%d\n", res1, res2);
printf("%d %d %s\n", resx + 1, resy + 1, dir == 1 ? "N" : "E");
}
return 0;
}
/*
5 5
3 2 6 3 6
1 8 4 1 4
13 7 13 9 4
3 0 2 6 5
9 8 8 12 13
*/
Ordered Fraction:
/*
ID: beihai2013
TASK: frac1
LANG: C++
*/
/*
每个分母存一个已经用了多少个分子的数组
如果分子和分母不是最简分数的话则跳过
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 160 + 5;
int num[MAXN];
int gcd(int a, int b){return b == 0 ? a : gcd(b, a % b);}
int main()
{
freopen("frac1.in", "r", stdin);
freopen("frac1.out", "w", stdout);
int n;
while(scanf("%d", &n) != EOF) {
for(int i = 1 ; i <= n ; i++) num[i] = 1;
printf("0/1\n");
int cnt = n * (n + 1) / 2 - n;
while(cnt > 0) {
int son, mother;
double res = 1;
for(int i = 1 ; i <= n ; i++) {
if(num[i] >= i) continue;
while(num[i] < i && gcd(num[i], i) != 1) {
num[i]++;
cnt--;
}
if(res > 1.0 * num[i] / (1.0 * i)) {
res = 1.0 * num[i] / (1.0 * i);
son = num[i], mother = i;
}
}
num[mother]++;
cnt--;
printf("%d/%d\n", son, mother);
}
printf("1/1\n");
}
return 0;
}
Sorting a Three-Value Sequence:
/*
ID: beihai2013
TASK: sort3
LANG: C++
*/
/*
首先确定排序后的序列是一定的,111 222 3333
然后分别知道1、2、3所在位置的合法区间[1,num[1]], [num[1]+1,num[1]+num[2]], [num[1]+num[2]+1,n],方便称为A、B、C
那么,在A区间里的2有限转移到B里,剩余转移到C;其余同理
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000 + 5;
int g[MAXN], cnt[4][4], n, num[4];
int calPos(int u){if(u <= num[1]) return 1; else if(u <= num[1] + num[2]) return 2; else return 3;}
int main()
{
freopen("sort3.in", "r", stdin);
freopen("sort3.out", "w", stdout);
while(scanf("%d", &n) != EOF) {
memset(num, 0, sizeof num);
memset(cnt, 0, sizeof cnt);
for(int i = 1 ; i <= n ; i++) {
scanf("%d", g + i);
num[g[i]]++;
}
for(int i = 1 ; i <= n ; i++) {
int mark = calPos(i);
cnt[mark][g[i]]++;
}
int res = 0;
if(cnt[1][2]) {
res += cnt[1][2];
int temp = min(cnt[1][2], cnt[2][1]);
cnt[1][2] -= temp;
cnt[2][1] -= temp;
cnt[3][2] += cnt[1][2];
}
if(cnt[1][3]) {
res += cnt[1][3];
int temp = min(cnt[1][3], cnt[3][1]);
cnt[1][3] -= temp;
cnt[3][1] -= temp;
cnt[2][3] += cnt[1][3];
}
if(cnt[2][3]) {
res += cnt[2][3];
// int temp = min(cnt[1][2], cnt[2][1]);
// cnt[1][2] -= temp;
// cnt[2][1] -= temp;
// cnt[3][2] += cnt[1][2];
}
printf("%d\n", res);
}
return 0;
}
Healthy Holsteins:
/*
ID: beihai2013
TASK: holstein
LANG: C++
*/
/*状压枚举*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 25 + 3;
int v[MAXN], w[MAXN][MAXN], n, m;
int tv[MAXN], out[MAXN], tout[MAXN];
int main()
{
freopen("holstein.in", "r", stdin);
freopen("holstein.out", "w", stdout);
while(scanf("%d", &n) != EOF) {
for(int i = 0 ; i < n ; i++) scanf("%d", v + i);
scanf("%d", &m);
for(int i = 0 ; i < m ; i++) for(int j = 0 ; j < n ; j++) scanf("%d", &w[i][j]);
int res = m + 1;
for(int i = 0 ; i < (1 << m) ; i++) {
for(int j = 0 ; j < n ; j++) tv[j] = 0;
for(int j = 0 ; j < m ; j++) {
if((1 << j) & i)
for(int k = 0 ; k < n ; k++) tv[k] += w[j][k];
}
int ok = 1;
for(int j = 0 ; j < n ; j++) if(tv[j] < v[j]) ok = 0;
if(ok == 1) {
int cnt = 0;
for(int j = 0 ; j < m ; j++) if((1 << j) & i) tout[cnt++] = j + 1;
if(res > cnt) {
res = cnt;
for(int j = 0 ; j < cnt ; j++) out[j] = tout[j];
}
else if(res == cnt) {
int tok = 0;
for(int j = 0 ; j < res ; j++) {
if(out[j] < tout[j]) break;
else if(out[j] > tout[j]) {
tok = 1;
break;
}
}
if(tok) for(int j = 0 ; j < res ; j++) out[j] = tout[j];
}
// if(cnt == 2 && tout[0] == 2 && tout[1] == 4) printf("i = %d\n", i);
}
}
printf("%d", res);
for(int i = 0 ; i < res ; i++) printf(" %d", out[i]);
puts("");
}
return 0;
}
Hamming Codes:
/*
ID: beihai2013
TASK: hamming
LANG: C++
*/
/*
我太蠢了……
这题就是贪心暴力,每次找最小的值满足条件,下一次找值找比这个值大的最小值,还想了各种奇怪的记忆化搜索……
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 64 + 5;
const int MAXM = 8 + 2;
int out[MAXN];
int n, b, d;
void dfs(int u, int cnt)
{
if(cnt == n) return;
out[cnt] = u;
for(int i = u + 1 ; i < (1 << b) ; i++) {
int ok = 0;
if(i == 127) ok = 1;
int num = b;
for(int j = 0 ; j <= cnt ; j++) {
int temp = out[j] ^ i;
int tnum = 0;
for(int k = 0 ; k < b ; k++) if((1 << k) & temp) tnum++;
// if(ok) printf("j = %d, out[j] = %d, temp = %d, tnum = %d\n", j, out[j], temp, tnum);
num = min(num, tnum);
}
if(num >= d) {
dfs(i, cnt + 1);
break;
}
}
}
int main()
{
freopen("hamming.in", "r", stdin);
freopen("hamming.out", "w", stdout);
while(scanf("%d%d%d", &n, &b, &d) != EOF) {
dfs(0, 0);
for(int i = 0 ; i < n ; i++) {
if(i % 10) printf(" ");
else if(i != 0) printf("\n");
printf("%d", out[i]);
}
printf("\n");
}
return 0;
}