Problem 1001
考虑到直接搜肯定TLE。
我们从起点开始搜10步,再从终点开始搜10步。
其中,从终点开始搜10步通过预处理完成,因为每一次的终点都是一样的。
存状态的时候我把0变成6(为了调试方便),把所有数字写在一行。
然后把这个大数看成一个7进制数,刚好在long long的范围内。
状态用map存储即可。
(幸好比赛的时候做出了这题……)
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
typedef long long LL;
const int N = (1 << 23) + 60;
const int Q = 63;
const LL w[Q] = {0, 6, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5};
LL bit[Q], pre;
int p[Q][Q], a[Q], T, pos, ans, cnt = 0;
vector <int> v[Q];
map <LL, int> MP, mp;
void dfs(int x, int z, LL now){
if (!mp[now]) mp[now] = x;
else mp[now] = min(mp[now], x);
if (x > 10) return;
for (auto u : v[z]){
LL ooo = 21 - z;
LL ol = now / bit[ooo];
LL lo = ol % 7;
LL eee = 21 - u;
LL el = now / bit[eee];
LL le = el % 7;
LL fff = now - lo * bit[ooo] - le * bit[eee] + lo * bit[eee] + le * bit[ooo];
dfs(x + 1, u, fff);
}
}
void pre_dfs(int x, int z, LL now){
if (!MP[now]) MP[now] = x;
else MP[now] = min(MP[now], x);
if (x > 10) return;
for (auto u : v[z]){
LL ooo = 21 - z;
LL ol = now / bit[ooo];
LL lo = ol % 7;
LL eee = 21 - u;
LL el = now / bit[eee];
LL le = el % 7;
LL fff = now - lo * bit[ooo] - le * bit[eee] + lo * bit[eee] + le * bit[ooo];
pre_dfs(x + 1, u, fff);
}
}
int main(){
bit[0] = 1;
rep(i, 1, 21) bit[i] = bit[i - 1] * 7LL;
rep(i, 1, 6){
rep(j, 1, i){
++cnt;
p[i][j] = cnt;
}
}
rep(i, 1, 6){
rep(j, 1, i){
int nx = i - 1, ny = j - 1;
if (nx > 0 && ny > 0 && p[nx][ny]){
v[p[i][j]].push_back(p[nx][ny]);
}
nx = i - 1, ny = j;
if (nx > 0 && ny > 0 && p[nx][ny]){
v[p[i][j]].push_back(p[nx][ny]);
}
nx = i + 1, ny = j;
if (nx > 0 && ny > 0 && p[nx][ny]){
v[p[i][j]].push_back(p[nx][ny]);
}
nx = i + 1, ny = j + 1;
if (nx > 0 && ny > 0 && p[nx][ny]){
v[p[i][j]].push_back(p[nx][ny]);
}
}
}
LL pre = 0;
rep(i, 1, 21) pre = pre * 7LL + w[i];
pre_dfs(1, 1, pre);
scanf("%d", &T);
while (T--){
mp.clear();
pos = 0;
rep(i, 1, 21){
scanf("%d", a + i);
if (a[i] == 0){
pos = i;
a[i] = 6;
}
}
LL st = 0;
rep(i, 1, 21) st = st * 7LL + a[i];
dfs(1, pos, st);
ans = 1 << 30;
bool fl = false;
for (auto pppp : MP){
LL ooo = pppp.first;
if (mp[ooo] > 0){
ans = min(ans, mp[ooo] - 1 + pppp.second - 1);
fl = true;
}
}
if (fl) printf("%d
", ans);
else puts("too difficult");
}
return 0;
}
Problem 1002
比赛时并未想到,觉得这是一个近似的等比数列
然后一直在找公比是多少,然而并未找到
赛后才发现,最后要求的数列也存在递推关系
(可以用数学方法解出)
只要找出相应的系数即可
然后用矩阵快速幂进行计算
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<vector> 9 #include<map> 10 #include<set> 11 #include<queue> 12 using namespace std; 13 typedef long long ll; 14 const ll mod=1e9+7; 15 int _; 16 struct matrix 17 { 18 ll a[2][2]; 19 matrix() 20 { 21 a[0][0]=a[1][1]=1; 22 a[0][1]=a[1][0]=0; 23 } 24 matrix operator *(const matrix &b) const 25 { 26 matrix ret; 27 ret.a[0][0] = ( a[0][0] * b.a[0][0] %mod+ a[0][1] * b.a[1][0] %mod) % mod; 28 ret.a[0][1] = ( a[0][0] * b.a[0][1] %mod+ a[0][1] * b.a[1][1] %mod) % mod; 29 ret.a[1][0] = ( a[1][0] * b.a[0][0] %mod+ a[1][1] * b.a[1][0] %mod) % mod; 30 ret.a[1][1] = ( a[1][0] * b.a[0][1] %mod+ a[1][1] * b.a[1][1] %mod) % mod; 31 return ret; 32 } 33 } C; 34 matrix pow_mod(matrix a,ll b) 35 { 36 matrix ans; 37 while (b) 38 { 39 if (b&1) ans=ans*a; 40 b>>=1; 41 a=a*a; 42 } 43 return ans; 44 } 45 ll get(ll n) 46 { 47 if (n==0) return 0; 48 if (n==1) return 1; 49 return pow_mod(C,n-1).a[0][0]; 50 } 51 int main() 52 { 53 C.a[0][0]=7; 54 C.a[0][1]=-4; 55 C.a[1][0]=1; 56 C.a[1][1]=0; 57 scanf("%d",&_); 58 while (_--) 59 { 60 ll n; 61 scanf("%lld",&n); 62 printf("%lld ",(get(n+1)-2*get(n)+mod*6)%mod); 63 } 64 }
Problem 1008
事实上,这是个最小点覆盖问题
设树上最大匹配数*2为tmp
如果k <tmp,那么答案为(k+1)/2
否则,答案为tmp/2+(k-tmp)
由于读入量大,还需要加人读入挂
1 #include <bits/stdc++.h> 2 3 namespace IO{ 4 const int MT = 50 * 1024 * 1024; 5 char IO_BUF[MT]; 6 int IO_PTR, IO_SZ; 7 8 void begin(){ 9 IO_PTR = 0; 10 IO_SZ = fread (IO_BUF, 1, MT, stdin); 11 } 12 template<typename T> 13 inline bool scan_d (T & t){ 14 while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != '-' && (IO_BUF[IO_PTR] < '0' || IO_BUF[IO_PTR] > '9'))IO_PTR ++; 15 if (IO_PTR >= IO_SZ) return false; 16 bool sgn = false; 17 if (IO_BUF[IO_PTR] == '-') sgn = true, IO_PTR ++; 18 for (t = 0; IO_PTR < IO_SZ && '0' <= IO_BUF[IO_PTR] && IO_BUF[IO_PTR] <= '9'; IO_PTR ++) 19 t = t * 10 + IO_BUF[IO_PTR] - '0'; 20 if (sgn) t = -t; 21 return true; 22 23 } 24 inline bool scan_s (char s[]){ 25 while (IO_PTR < IO_SZ && (IO_BUF[IO_PTR] == ' ' || IO_BUF[IO_PTR] == ' ') ) IO_PTR ++; 26 if (IO_PTR >= IO_SZ) return false; 27 int len = 0; 28 while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != ' ' && IO_BUF[IO_PTR] != ' ') 29 s[len++] = IO_BUF[IO_PTR], IO_PTR ++; 30 s[len] = '