Table of Contents
2020.7.6 热身训练赛(六)
A Rush Hour Puzzle
solution
bfs.
-
状态用一个结构体保存;
-
状态判重用set;
-
当把结构体放入set中时,要对 “<” 进行重载。
friend bool operator < (node p, node q) { }
-
每次移动等价于0和一个数字位置的交换。这样只用考虑0就行了。
-
只有一个出口。
code
#include <bits/stdc++.h>
using namespace std;
struct node {
int mp[6][6],mov;
friend bool operator < (node p, node q) {
for (int i = 0; i< 6; ++i)
for (int j = 0; j<6; ++j)
if (p.mp[i][j] != q.mp[i][j]) return p.mp[i][j] < q.mp[i][j];
return 0;
}
}st;
queue<node>q;
set<node>vis;
int to[4][2] = {0,1,0,-1,1,0,-1,0};
inline bool inrg(int x,int y){
return x>=0&&x<6&&y>=0&&y<6;
}
int main() {
for (int i = 0; i< 6; ++i){
for (int j = 0; j<6; ++j){
scanf("%d", &st.mp[i][j]);
}
}
st.mov = 0;
q.push(st);
vis.insert(st);
while(q.size()) {
node u = q.front(),nu;
q.pop();
if (u.mp[2][5] == 1) {
int len = 1;
for (int i = 4; i >=0; --i) {
if (u.mp[2][i]!=1) break;
++len;
}
int ans = (u.mov + len);
if (ans > 10) ans = -1;
printf("%d
", ans);
return 0;
}
if (u.mov == 10) break;
for (int i = 0; i< 6; ++i) {
for (int j = 0; j<6; ++j) {
if (u.mp[i][j] == 0) {
for (int k = 0; k < 4; ++k) {
int x = i+to[k][0], y = j+to[k][1];
if((!inrg(x,y))||u.mp[x][y] == 0) continue;
int xx = x+to[k][0], yy = y +to[k][1];
if((!inrg(xx,yy))||u.mp[x][y]!=u.mp[xx][yy]) continue;
while(inrg(xx,yy)&&u.mp[x][y]==u.mp[xx][yy]){
xx = xx+to[k][0];
yy = yy+to[k][1];
}
xx = xx-to[k][0];
yy = yy-to[k][1];
nu = u;
++nu.mov;
swap(nu.mp[i][j],nu.mp[xx][yy]);
if(!vis.count(nu)) {
vis.insert((nu));
q.push(nu);
}
}
}
}
}
}
printf("-1
");
return 0;
}
H Mining a
这个不会证明。
E The League of Sequence Designers
solution
构造题,假设答案序列a的长度为n,且a[1] = -1,a[i] >=0,sum a[i] = m(2<=i<=n),则按照错误方法算出来的结果为 (n-1)*m,假设按照正确方法算出来的结果为 n*(m-1) (即 n*(m-1) > (n-1)*m), 由题意可得 n*(m-1) - (n-1)*m = k. 解得 m =n + k. 也就是构造一个a[1] = -1, sum a[i] = n + k(2<=i<=n, a[i]<=1e9)的序列即可。
code
#include<cstdio>
#include<iostream>
using namespace std;
const int len = 1999;
const int Max = 1000000;
int main()
{
int T;
cin>>T;
while(T--)
{
long long K,L;
cin>>K>>L;
if(L>=2000){
puts("-1");
continue;
}
printf("%d
-1",len);
long long now= len +K;
for(int i =1;i<len;i++)
{
if(now>=Max)
{
printf(" %d",Max);
now-=Max;
}
else
{
printf(" %d",now);
now=0;
}
}
puts("");
}
}