day-1
bfs 保存路径
https://codeforces.com/contest/1534/problem/E
本质是:n个硬币,每次可以将k个硬币翻面,问最少需要多少次就能将所有硬币从正面翻转到反面
需要bfs搜索出最优路径并且需要记录前驱。
const int maxn = 1e6 + 7;
const int mod = 1e9 + 7;
int n, t, k, dis[maxn], pre[maxn], col[maxn];
stack<int> path;
void bfs()
{
for (int i = 0; i <= n; i++)
dis[i] = mod, col[i] = 0;
queue<int> que;
pre[0] = -1, que.push(0), dis[0] = 0;
while (que.size()) {
int now = que.front();
que.pop();
for (int x = 0; x <= k; x++) {
int to = now + k - 2 * x;
if (to > n || to < 0 || x > now || k - x > n - now)
continue;
if (dis[to] > dis[now] + 1)
dis[to] = dis[now] + 1, pre[to] = now, que.push(to);
}
}
while (path.size())
path.pop();
for (int c = n; c != -1; c = pre[c]) {
if (pre[c] == -1)
continue;
path.push(c - pre[c]);
}
}
void solve()
{
if (dis[n] == mod) {
cout << "-1" << endl;
return;
}
int ans = 0, as;
while (path.size()) {
int c = path.top();
path.pop();
cout << "? ";
int zcnt = k - c >> 1, ocnt = k - zcnt;
for (int i = 1, o = 0, c = 0; i <= n; i++) {
if (o < ocnt && col[i] == 0) {
col[i] = 1, o++;
cout << i << " ";
} else if (c < zcnt && col[i] == 1) {
col[i] = 0, c++;
cout << i << " ";
}
}
cout << endl;
cout.flush();
cin >> as;
ans ^= as;
}
cout << "! " << ans << endl;
}
int main()
{
// cin >> t;
// while (t--) {
cin >> n >> k;
bfs();
solve();
// }
}
7.25 重写
注意枚举翻到正面个数的范围 path要明白是啥意思...
const int maxn = 1e4 + 7;
int n, k;
int dis[maxn], path[maxn];
void bfs() {
dis[0] = 0;
queue<int> que;
que.push(0);
while (que.size()) {
int tp = que.front();
que.pop();
for (int c = 0; c <= k; c++) {
int nx = tp + c - (k - c);
if (nx <= 0 || nx > n || k - c > tp || c > n - tp)
continue;
if (dis[nx] > dis[tp] + 1) {
dis[nx] = dis[tp] + 1;
path[nx] = c;
que.push(nx);
}
}
}
}
void solve() {
memset(dis, 0x3f, sizeof dis);
cin >> n >> k;
bfs();
if (dis[n] > 1e5) {
cout << -1 << endl;
return;
}
vector<int> vec;
int nx = n;
while (nx)
vec.push_back(path[nx]), nx = nx - (path[nx] - (k - path[nx]));
reverse(vec.begin(), vec.end());
queue<int> good, bad, tp, tp_;
for (int i = 1; i <= n; ++i)
bad.push(i);
int ans = 0;
for (int i = 0, c; i < vec.size(); i++) {
cout << "? ";
c = vec[i];
for (int j = 0; j < c; ++j)
tp.push(bad.front()), bad.pop();
for (int j = 0; j < k - c; j++)
tp_.push(good.front()), good.pop();
while (tp.size())
cout << tp.front() << " ", good.push(tp.front()), tp.pop();
while (tp_.size())
cout << tp_.front() << " ", bad.push(tp_.front()), tp_.pop();
cout << endl;
cin >> c;
ans ^= c;
}
cout << "! " << ans << endl;
}
配置manjaro:
1.vmware
2.vscode gdb...
3.fictx5
我看见 你