(有问题欢迎提出来
文章目录
A:Potato Sacks
Solved.
没看这题。
int dp[50];
int main() {
int t;
scanf("%d",&t);
int pos=0;
while(t--) {
int mx;
scanf("%d%d",&pos,&mx);
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=0;i<10;i++){
int a;
scanf("%d",&a);
for(int i=mx-a;i>=0;i--)
dp[i+a]=dp[i]|dp[i+a];
}
printf("%d ",pos);
puts(dp[mx]?"YES":"NO");
}
return 0;
}
B:Moving Buildings
Unsolved.
神奇的汉诺塔。
C:Hedwig’s Ladder
Solved.
写完发现就一个样例没过,比答案多1。自己手算之后发现自由偶数才会多1,犹豫要不要交。。。经过长时间神游后。。。打表发现真的是这样的。。。就过了。
int main() {
c[1] = 2; c[2] = 4;
for(int i = 3; i <= 1000; ++i) {
c[i] = (c[i-1] + c[i-2])%mod;
}
int t;scanf("%d",&t);
while(t--) {
int n, x; scanf("%d%d",&x, &n);
LL ans = c[n];
if(n%2==0) ans = (ans-1+mod)%mod;
printf("%d %lld\n", x, ans);
}
return 0;
}
E:What time is it anyway?
Solved.
sb的bug,删掉一句话就过了。。。一摸一样的写法,只能让队友重写了一遍,然后过了。。。
const int maxn=1e6+5;
map<pii, int> mp, mp1;
pii now[maxn], cha[maxn];
char s[maxn];
int main() {
int t;scanf("%d",&t);
while(t--) {
int n, x;
mp.clear();
scanf("%d%d",&x, &n);
for(int i = 0; i < n; ++i) {
scanf("%s", s);
int a = 0, b = 0, len = strlen(s), flag = 1;
for(int j = 0; j < len; ++j) {
if(s[j] == ':') {
flag = 0;continue;
}
if(flag) a = a * 10 + s[j]-'0';
else b = b * 10 + s[j]-'0';
}
now[i] = {a, b};
assert(b>=0);assert(b<60);
}
for(int i = 0; i < n; ++i) {
scanf("%s", s);
int a = 0, b = 0, len = strlen(s), flag = 1, f = 1;
if(s[0] == '+') f = 0;
for(int j = 1; j < len; ++j) {
if(s[j] == ':') {
flag = 0;
continue;
}
if(flag) a = a * 10 + s[j]-'0';
else b = b * 10 + s[j]-'0';
}
a %= 12;
if(f == 0) {
if(b == 0) a = 12 - a;
else {
a = 11 - a;b = 60 - b;
}
}
a %= 12;
cha[i] = {a, b};
assert(b>=0);assert(b<60);
mp[cha[i]]++;
}
pii aa;
int cnt = 0;
mp1.clear();
for(int i = 0; i < n; ++i) {
int a = now[0].fi + cha[i].fi, b = now[0].se + cha[i].se;
if(b >= 60) a += b/60, b %= 60;
a %= 12;
pii tmp = {a, b};
mp[cha[i]] --;
int flag = 1;
for(int j = 1; j < n; ++j) {
int x = 12, y = tmp.se-now[j].se;
if(y < 0) y += 60, x = 11;
x += tmp.fi-now[j].fi;
x = (x+12)%12;
assert(y >= 0); assert(y < 60);
if(mp[make_pair(x, y)] == 0) {
flag = 0;
break;
}
mp[make_pair(x, y)] --;
}
if(flag && mp1[tmp] == 0) {
cnt++;
aa = tmp;
mp1[tmp] = 1;
}
mp.clear();
for(int j = 0; j < n; ++j) mp[cha[j]]++;
}
printf("%d ", x);
if(aa.fi == 0) aa.fi = 12;
if(cnt == 0) printf("none\n");
else if(cnt == 1) printf("%d:%02d\n", aa.fi, aa.se);
else printf("%d\n",cnt);
}
return 0;
}
F:Left-Right-Win
Unsolved.
G:The Erdös-Straus Conjecture
Upsolved.
暴力枚举
a
:
[
n
/
4
+
1
,
n
/
4
+
10
]
a:[n/4+1,n/4+10]
a:[n/4+1,n/4+10],得到分数
x
y
\frac xy
yx,暴力枚举
b
b
b:
[
y
/
x
+
1
,
2
∗
y
/
x
]
[y/x+1,2*y/x]
[y/x+1,2∗y/x],就可以过了。
#include<bits/stdc++.h>
#define fi first
#define se second
#define eb emplace_back
using namespace std;
//typedef __int128 LL;
typedef long long LL;
typedef pair<int, int> pii;
const int MXN = 5e4 + 5;
int n;
struct lp {
uLL a, b, c;
}cw[MXN];
LL gcd(LL a, LL b) {
return b==0?a:gcd(b, a%b);
}
void solve(int n) {
if(n == 2) {
cw[n] = {1, 2, 2};return ;
}
LL a = n / 4 + 1, b, c, last = n / 4 + 10;
LL x, y, x1, y1, tmp;
int flag = 0;
while(a <= last) {
y = a * n;
x = 4 * a - n;
//printf("-%lld %lld\n", x, y);
tmp = gcd(x, y);
x /= tmp; y /= tmp;
//printf("%lld %lld %lld*\n", a, x, y);
LL tb = y / x + 1, bmax = 2*y/x;
//printf("%lld %lld**\n", tb, bmax);
for(; tb <= bmax; ++tb) {
b = tb;
y1 = tb * y;
x1 = x * tb - y;
if(y1 % x1 == 0) {
c = y1/x1;
flag = 1;
break;
}
}
if(flag) break;
++ a;
}
cw[n] = {a, b, c};
}
int main() {
//for(int i = 4560; i <= 4660; ++i) solve(i),cout<<i<<" ";
int tim, x; scanf("%d", &tim);
while(tim --) {
scanf("%d%d", &x, &n);printf("%d ", x);
solve(n);
printf("%lld %lld %lld\n", cw[n].a, cw[n].b, cw[n].c);
}
return 0;
}
H:Subprime Fibonacci Sequence
Solved.
一道sb题,我一直在想怎么快速找循环节。。。结果题目直接把方法告诉你了。。
#include<bits/stdc++.h>
using namespace std;
const int MXN = 1e6 + 4;
int noprime[MXN], pp[MXN], pcnt, minp[MXN];
int f[MXN];
void init() {
noprime[0] = noprime[1] = 1;
minp[1] = 1;
for(int i = 2; i < MXN; ++i) {
if(!noprime[i]) pp[pcnt++] = i, minp[i] = i;
for(int j = 0; j < pcnt && pp[j]*i < MXN; ++j) {
noprime[pp[j]*i] = 1;
minp[i*pp[j]] = i;
if(i % pp[j] == 0) break;
}
}
}
int main() {
fin();
init();
int caset;
scanf("%d", &caset);
while(caset--) {
int x, n, a0, a1;
scanf("%d%d%d%d", &x, &n, &a0, &a1);
f[0] = a0;
f[1] = a1;
for(int i = 2; i <= n+1; ++i) {
f[i] = minp[f[i-1]+f[i-2]];
}
int k = -1, k1 = -1;
for(int i = 0; i < n - 1; ++i) {
if(f[i] == f[n-2] && f[i+1] == f[n-1]) {
k = i;break;
}
}
for(int i = k+1; i < n - 1 && k != -1; ++i) {
if(f[i] == f[k] && f[i+1] == f[k+1]) {
k1 = i;break;
}
}
int lca = k1-k;
int fir = k, tmp = n-2;
while(fir >= 0) {
if(f[fir] != f[tmp]) break;
-- fir; -- tmp;
}
fir ++;
if(k1 == -1) {
printf("%d %d %d\n", x, n, 0);
printf("%d\n", f[n]);
continue;
}
printf("%d %d %d\n", x, lca + fir + 1, lca);
assert(lca >= 1);
int last = 0;
for(int i = fir, j = 1; j <= lca + 2; ++i, ++j) {
printf("%d", f[i]);
if((j % 20 == 0)) printf("\n"), last = 1;
else printf(" "), last = 0;
}
if(last == 0) printf("\n");
}
return 0;
}
J:Pinemi Puzzles
Upsolved.
数独:
d
f
s
dfs
dfs+剪枝
c
a
m
p
camp
camp里
d
l
s
dls
dls也出了一道这种题
剪枝1:
记录每行每列空着的格子数量和已经填的棒子的数量。搜索过程中要保证一定凑出每行每列10个棒子。
k
o
n
g
[
x
]
kong[x]
kong[x]表示这一行或这一列空着的格子的数量(也就是
−
1
-1
−1的数量);
s
u
m
[
x
]
sum[x]
sum[x]表示这一行或这一列已经填了的棒子的数量。
如果
k
o
n
g
[
x
]
>
10
−
s
u
m
[
x
]
kong[x]\gt 10-sum[x]
kong[x]>10−sum[x]则
c
o
n
t
i
n
u
e
continue
continue,因为每个格子至少放一个棒子。
如果
k
o
n
g
[
x
]
∗
3
<
10
−
s
u
m
[
x
]
kong[x]*3\lt 10-sum[x]
kong[x]∗3<10−sum[x]则
c
o
n
t
i
n
u
e
continue
continue,因为每个格子至多放三个棒子。
剪枝2:
记录每个数字周围空着的格子数量和已经填的棒子的数量。
剪枝方法同上。
这个剪枝要把每个
−
1
-1
−1的格子旁边的正数的位置预处理存起来会快一点。
有了这两个剪枝基本上这题就过了。
#include<bits/stdc++.h>
#define fi first
#define se second
#define eb emplace_back
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int MXN = 4e5 + 7;
int n, m;
int ar[11][11], ans[11][11], nd[11][11], bl[11][11];//储存周围需要的棍子数量
int dir[8][2] = {1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1};
std::vector<int> rm[11*11];//储存-1周围有需要的格子
std::vector<int> vs;
int kong[11+11], sum[11+11];//每行每列空着的位置和已经填的棒子数量
int flag;
bool check(int x, int y, int v) {
int id = (x-1)*10 + y, px, py;
if(v > 0) {
if(kong[x] == 1 && sum[x] + v != 10) return 0;
if(kong[10+y] == 1 && sum[10+y] + v != 10) return 0;
if(sum[x] + v > 10) return 0;
if(sum[10+y] + v > 10) return 0;
if(10-sum[x]-v < kong[x]-1) return 0;
if(10-sum[x]-v > 3*(kong[x]-1)) return 0;
if(10-sum[10+y]-v > 3*(kong[10+y]-1)) return 0;
}
for(auto as: rm[id]) {
px = (as-1)/10+1, py = as % 10;
py = (py==0?10:py);
if(v > nd[px][py]) return 0;
if(bl[px][py] == 0 || nd[px][py] == 0) return 0;
if(nd[px][py] - v < bl[px][py] - 1) return 0;
if(nd[px][py] - v > 3*(bl[px][py] - 1)) return 0;
}
return 1;
}
void gao(int x, int y, int v) {
int id = (x-1)*10 + y, px, py;
if(v > 0) kong[x] --, kong[10+y]--,sum[x]+=v,sum[10+y]+=v;
else kong[x] ++, kong[10+y]++,sum[x]+=v,sum[10+y]+=v;
for(auto as: rm[id]) {
px = (as-1)/10+1, py = as % 10;
py = (py==0?10:py);
nd[px][py] -= v;
if(v < 0) bl[px][py] += 1;
else bl[px][py] -= 1;
}
}
void dfs(int now, int remain) {
if(remain == 0) {
flag = 1;
return;
}
if(flag) return ;
int x = (vs[now]-1)/10+1, y = vs[now] % 10;
y = (y==0?10:y);
for(int i = 1; i <= 3; ++i) {
if(check(x, y, i)) {
ans[x][y] = i;
gao(x, y, i);
dfs(now+1, remain-1);
if(flag) return ;
gao(x, y, -i);
}
}
}
int main() {
int tim; scanf("%d", &tim);
while(tim --) {
scanf("%d", &m);
memset(bl, 0, sizeof(bl));
memset(nd, 0, sizeof(nd));
memset(kong, 0, sizeof(kong));
memset(sum, 0, sizeof(sum));
flag = 0;
for(int i = 0; i <= 101; ++i) rm[i].clear();
vs.clear();
printf("%d\n", m);
for(int i = 1; i <= 10; ++i) for(int j = 1; j <= 10; ++j) scanf("%d", &ar[i][j]),ans[i][j]=ar[i][j];
for(int i = 1; i <= 10; ++i) {
for(int j = 1; j <= 10; ++j) {
nd[i][j] = ar[i][j];
if(ar[i][j] == -1) {
++ kong[i];
++ kong[10+j];
vs.push_back((i-1)*10+j);
for(int h = 0, px, py; h < 8; ++h) {
px = i + dir[h][0], py = j + dir[h][1];
if(px < 1 || py < 1 || px > 10 || py > 10) continue;
if(ar[px][py] != -1) {
rm[(i-1)*10+j].push_back((px-1)*10+py);
}
}
}else {
for(int h = 0, px, py; h < 8; ++h) {
px = i + dir[h][0], py = j + dir[h][1];
if(px < 1 || py < 1 || px > 10 || py > 10) continue;
if(ar[px][py] == -1) ++ bl[i][j];
}
}
}
}
n = vs.size();
dfs(0, n);
for(int i = 1; i <= 10; ++i) {
for(int j = 1; j <= 10; ++j) {
assert(ans[i][j] != -1);
if(ar[i][j] == -1) continue;
int tmp = 0;
for(int h = 0, px, py; h < 8; ++h) {
px = i + dir[h][0], py = j + dir[h][1];
if(px < 1 || py < 1 || px > 10 || py > 10) continue;
if(ar[px][py] == -1) tmp += ans[px][py];
}
assert(ans[i][j] == ar[i][j]);
assert(tmp == ar[i][j]);
}
}
for(int i = 1; i <= 10; ++i) {
for(int j = 1; j < 10; ++j) printf("%d ", ans[i][j]);
printf("%d\n", ans[i][10]);
}
}
return 0;
}