题意:略
思路:总HP最多队伍获胜
void solve()
{
ve<int> a(6),b(6);
int sa=0,sb=0;
fo(i,1,5) cin >> a[i],sa+=a[i];
fo(i,1,5) cin >> b[i],sb+=b[i];
if(sa < sb) cout << "Red" << endl;
else cout << "Blue"<<endl;
}
题意:已知八个点是否可以构成一个立方体
思路:
八个点两两连接共有28条边
有三种长度1,√2,√3
数量之比为12/12/4
长度的平方之比为1/2/3
int l[N];
void solve()
{
ve<int> x(9),y(9),z(9);
fo(i,1,8) cin >> x[i] >> y[i] >> z[i];
int tt = 0;
fo(i,1,8)
fo(j,i+1,8)
l[++tt] = (x[j]-x[i])*(x[j]-x[i]) + (y[j]-y[i])*(y[j]-y[i]) + (z[j] - z[i])*(z[j] - z[i]);
sort(l+1,l+1+28);
if(l[1] != 0 and l[13] == l[24] and l[13] == 2 * l[1] and l[25] == 3*l[1] and l[25] == l[28] and l[1] == l[12])
YES;
else NO;
}
题意:操作1: n --
操作2:m++
问最少操作多少次,使得 m % n == 0
思路:
当n > m时 操作n - m 次
当n < m 时
设:
则当前的m最小为 *i, ans = *i - m+n-i
ans = (-1)*i+n-m
ans = (-1)*i+n-m
ans = *i+n-m
此时分块维护,记录答案即可
void solve()
{
ll n, m;
cin >> n >> m;
if(n > m) {cout << n - m << endl;return;}
ll ans = 1e10;
ll r;
for(ll l = 1; l <= n; l =r+1)
{
r = min(n, (m-1)/((m-1)/l));
ans = min(ans, (m-1)/l*l);
}
cout << ans + n - m << endl;
}
题意:操作1:在图上添加点,并和相邻的块联通
操作2:查询这个点的联通块,输出边的数量
思路:
考虑用冰茶几维护
对于操作1,可以将坐标离散化之后丢到冰茶几
对于操作2,维护一下冰茶几内点的数量和邻边的个数,输出sz*6-2*rl
ll p[N];
ll sz[N], rl[N];
int dx[] = {-1,-1,0,0,1,1};
int dy[] = {0,1,-1,1,0,-1};
ll find(ll x){return x == p[x] ? x : p[x] = find(p[x]);}
ll tt = 0;
map<PII,ll> mp;
void solve()
{
int sg;
cin >> sg;
fo(i,0,sg) p[i] = i;
fo(i,1,sg)
{
ll op,x,y;
cin >> op >> x >> y;
if(op == 1)
{
PII t = {x,y};
++tt;
mp[t] = tt;
sz[tt] = 1;
rl[tt] = 0;
fo(i,0,5)
{
ll nx = dx[i] + x, ny = dy[i] + y;
PII nt = {nx,ny};
if(!mp.count(nt)) continue;
ll pa = find(mp[nt]);
if(pa != tt)
{
p[pa] = tt;
rl[tt] += rl[pa]+1;
sz[tt] += sz[pa];
}
else rl[tt] ++;
}
}
else
{
PII t = {x,y};
if(!mp.count(t)) cout << 6 << endl;
else
{
ll pa = find(mp[t]);
cout << sz[pa]*6-rl[pa]*2<<endl;;
}
}
}
}
题意:给三个绳结,告诉六个蓝色点处,是否编号大的圆在上,回答存在多少张方案,可以使3个环拆开
思路:
共有8种操作:以下表示剪开哪个圆,0表示不操作
1|2|3|1 2|1 3|2 3|1 2 3|0
对于一对点,如果上下不同,则表示存在一个结 jie
jie == 1 剪开两个圆其中一个即可,共有6种方案
jie == 2 要么剪开中间的圆,要么两边的都剪掉,5种方案
jie == 3 剪开三个圆中的两个,4种方案
jie == 0 若1在2上,2在3上,3在1上,则剪掉其中一个即可,有7种方案
否则不需要操作,有8种方案
int p[6][6];
int ck[6][6];
void solve()
{
// 1, 2, 3, 1 2, 1 3, 2 3, 1 2 3; 0 // 8
// 0 8
// 1 6
// 2 (3,1 2, 1 2 3, 1 3, 1 2)
// 3 (1 2, 1 3, 2 3, 1 2 3 )
// 1->2 2->3 3->1 7
fo(i,0,1) fo(j,1,3)
{
string s;
cin >> s;
p[j][i] = s == "true";
}
int jie = 0;
fo(i,1,3) if(p[i][0] != p[i][1]) jie ++;
if(jie == 1)
{
cout << 6 << endl;
}
else if(jie == 2) cout << 5 << endl;
else if(jie == 3) cout << 4 << endl;
else if(jie == 0)
{
fo(i,1,3) fo(j,i+1,3)
{
int u;
if(i == 1 and j == 2) u = 1;
if(i == 1 and j == 3) u = 2;
if(i == 2 and j == 3) u = 3;
if(p[u][0] == p[u][1])
{
if(p[u][0] == 1) ck[j][i] = 1;
else ck[i][j] = -1;
}
}
fo(i,1,3)
fo(j,1,3)
{
if(i == j) continue;
fo(k,1,3)
{
if(i == k or j == k) continue;
if(ck[i][j] == ck[j][k] and ck[k][i] == ck[j][k])
{
cout << 7 << endl;
return;
}
}
}
cout << 8 << endl;
}
}
题意:图上有n个点,每个节点上(除了1)都有无限份价值为v的财宝,一个人可以从节点1出发到每个节点上拿,每次只能拿一份,请问t=1~T的时间内,最多能拿价值多少的财宝
思路:
从节点1开始,将到某个节点取财宝所花费的时间作为消耗,于是只需要跑一遍从1开始的最短路,最后做一个完全背包即可
int a[N];
ve<int> g[N];
int ds[N];
bool st[N];
int f[N];
void solve()
{
int n, m, T;
cin >> n >> m >> T;
fo(i,2,n) cin >> a[i];
fo(i,1,m)
{
int u, v;
cin >> u >> v;// fuck ep:刚开始忘记输入,调了很久
if(u == v) continue;
g[u].pb(v);
g[v].pb(u);
}
priority_queue<PII, ve<PII> ,greater<PII> > q;
fo(i,1,n) ds[i] = inf;
q.push({0,1});
ds[1] = 0;
while(!q.empty())
{
auto t = q.top();
q.pop();
int u = t.se, w = t.fi;
if(st[u]) continue;
st[u] = 1;
//out(g[u][0]);
for(auto v : g[u])
{
if(ds[v] > w + 1)
{
ds[v] = w + 1;
q.push({ds[v],v});
}
}
}
fo(i,1,n)
fo(j,ds[i]*2,T)
f[j] = max(f[j], f[j - ds[i]*2] + a[i]);
cout << 0 <<" ";
fo(i,2,T) cout <<f[i] << " ";
}
题意:给一个字符串T和一份代码,问在匹配时是否存在一个字符串S使答案错误
思路:
nxt数组大于0时会出错,这个代码只会回跳到1的位置
int nxt[N];
void solve()
{
int n;
string t;
cin >> n >> t;
nxt[0] = -1;
int i = 0, j = -1;
while(i < n)
{
if(j == -1 or t[i] == t[j]) nxt[++i] = ++j;
else j = nxt[j];
}
int len = nxt[n];
bool ok = 0;
fo(i,0,n) if(nxt[i] > 0) ok = 1;
if(ok) cout << "Wrong Answer" << endl;
else cout << "Correct"<<endl;
}
题意:
A给B x分
B给A y分
x > y, A+10分
x < y, B+10分
思路:
两人是对等的,期望为0
solve()
{
int n;
cin >> n;
cout << 0 << endl;
}