http://poj.openjudge.cn/campus2012/
Problem A. Hand Evaluation
Brief description:
略。)
Analysis:
签到。)
Problem C. Lausanne Capitale Olympique
Brief description:
给定一个图,问是否从源点出发,到任意点的最短路径和次短路径的长度相差不超过 1 。。。
Analysis:
做一次 bfs() 对所有不在最短路径树中的边,如果连接两点的层次一样则同时标记这两个顶点。。如果一高一低则标记高点。。
返回标记的顶点数是否 == n。
const int N = 10009;
VI adj[N]; MIB used[N]; int q[N], d[N], head, tail;
bool bj[N]; int cnt;
int n, m;
void init(){
REP(i, n) CLR(adj[i]), CLR(used[i]);
int x, y; REP(i, m){
RD(x, y); --x, --y;
adj[x].PB(y), adj[y].PB(x);
}
}
void bfs(){
RST(d), d[0] = 1, q[head = 0] = 0, tail = 1;
while (head < tail){
int u = q[head++];
#define v adj[u][i]
REP(i, SZ(adj[u])) if (!d[v]){
d[v] = d[u] + 1, used[u][v] = used[v][u] = true;
q[tail++] = v;
}
}
}
void tick(int x){
if (!bj[x]) bj[x] = true, ++cnt;
}
int check(){
RST(bj); bj[0] = true, cnt = 1;
REP(u, n) REP(i, SZ(adj[u])) if (!used[u][v]){
if (d[u] == d[v]) tick(u), tick(v);
else tick(d[u] > d[v] ? u : v);
}
return cnt == n;
}
int main(){
while (scanf("%d %d", &n, &m) != EOF){
init(); bfs();
cout << check() << endl;
}
}
Problem F. Game
。。先写个程序暴力一下 SG 。。。
const int N = 1024;
int SG[N], n;
VI tmp;
int mex(VI& tmp){
if (tmp[0] != 0) return 0;
FOR(i, 1, SZ(tmp)) if (tmp[i] - tmp[i-1] != 1){
return tmp[i-1] + 1;
}
return tmp[SZ(tmp) - 1] + 1;
}
int main(){
freopen("out.txt", "w", stdout);
n = 1024;
SG[0] = 1, SG[1] = 0;
FOR(i, 2, n){
CLR(tmp); REP_1(j, i/2) tmp.PB(SG[i - j] ^ SG[i - 2 * j]);
SRT(tmp); tmp.resize(unique(ALL(tmp)) - tmp.begin()); SG[i] = mex(tmp);
}
REP(i, n){
if (!SG[i] && !SG[i+1]) cout << endl;
cout << SG[i];
}
}
稍微整理下得到以下数据。。
1 0 010 012210 010 012214414412210 010 012210 01 001221441441221771771221771771221441441221 001 001221 001 001221441441221 001 001221 001 001221441441221771771221771771221441441221881881221881881221441441221881881221881881221441441221771771221771771221441441221 001 001221 001 001221441441221 001 001221 001 001221441441221771771221771771221441441221 001 001221 001 001221441441221 001 001221 001 00122144144122177177122177177122144144122188188122188188122144144122188188122188188122144144122177177122177177122144144122111111111112211111111111221441441221111111111122111111111112214414412217717712217717712214414412211111111111221111111111122144144122111111111112211111111111221441441221771771221771771221441441221881881221881881221441441221881881221881881221441441221771771221771771221441441221
这样规律性就已经显现了。。中间的 Pattern 类似某种树状数组的东西。。
中间又出现了 1, 2, 5, 14, 51, 152 这样的数列。。(差分一下是 a[n] = 3n – 1)。。。
。。重新整理。。
const int N = 1<<10;
int SG[N], n;
VI tmp;
int mex(VI& tmp){
if (tmp[0] != 0) return 0;
FOR(i, 1, SZ(tmp)) if (tmp[i] - tmp[i-1] != 1){
return tmp[i-1] + 1;
}
return tmp[SZ(tmp) - 1] + 1;
}
int main(){
freopen("out.txt", "w", stdout);
n = N;
SG[0] = 1, SG[1] = 0;
FOR(i, 2, n){
CLR(tmp); REP_1(j, i/2) tmp.PB(SG[i - j] ^ SG[i - 2 * j]);
SRT(tmp); tmp.resize(unique(ALL(tmp)) - tmp.begin()); SG[i] = mex(tmp);
}
int cnt = 0; REP(i, n){
printf("%c", (SG[i] <= 10 ? '0' : ('A' - 10)) + SG[i]);
if (!SG[i]){
if (++cnt&1) cout << endl;
}
}
}
Problem H. Gugle Seating
Brief description:
给一个N*M的矩阵,每个位置上可以有电脑(2)或者椅子(1)或者空(0)。如下面的矩阵
3 4 2 2 1 2 0 1 2 2 2 2 2 1
每个工程师需要占用一个椅子 + 两个和椅子相邻且成直角关系的电脑。如:
1 2 2
问最多能安排多少个工程师进来。电脑只能同时给一个人,椅子也是。
Analysis:
S -> (奇数列) 电脑-> 人 -> (偶数列) 电脑 -> T
中间椅子拆点以保证每个椅子只会被计数一次。
https://gist.github.com/lychees/7306034




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
