review
AT193
将n个数从小到大排序,挨个输出
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
string a[105];
int n,m;
bool cmp(string x,string y){
return x+y>y+x;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
cout<<a[i];
}
cout<<"
";
return 0;
}
CF898D
将闹钟响的时间排序,枚举 (i),如果 (a_i) 到 (a_i + m) 这个区间内有大于k 个闹钟的话,就贪心将后面的删去,直到这个区间内只有 k 个为止
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
const int N = 2e5 + 10, M = 1e6 + 10;
int n, m, k;
int a[N], cnt;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i)
cin >> a[i];
sort(a + 1, a + n + 1);
deque<int> dq;
for (int i = 1; i <= n; ++i)
{
while (dq.size() && dq.front() <= a[i] - m)
dq.pop_front();
dq.push_back(a[i]);
while (dq.size() >= k)
++cnt, dq.pop_back();
}
cout << cnt << endl;
return 0;
}
//
CF898C
将每一个人的号码排序,判断是否存在后缀的情况,有就删,没有就保留
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 25;
map<string,vector<string> >mp;
bool cmp(string s1,string s2)
{
return s1<s2;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
string name,ss;
for(int i=1; i<=n; i++)
{
cin>>name;
int m;
cin>>m;
while(m--)
{
cin>>ss;
reverse(ss.begin(),ss.end());//先翻转存入便于判断后缀
mp[name].push_back(ss);
}
}
cout<<mp.size()<<endl;
map<string,vector<string> >::iterator it;
for(it=mp.begin(); it!=mp.end(); it++)
{
string str[1000],ans[1000];
cout<<it->first<<" ";
vector<string>v=it->second;
int len=v.size();
for(int i=0; i<len; i++)
{
str[i]=v[i];
}
sort(str,str+len,cmp);
int i,j,k=0;
for(i=0; i<len; i++)
{
int temp,flag=0;
for(j=i+1; j<len; j++)
{
temp=str[j].find(str[i]);
if(temp==0)
{
flag=1;
break;
}
}
if(flag==0)
{
ans[++k]=str[i];
}
}
cout<<k;
for(int i=1; i<=k; i++)
{
reverse(ans[i].begin(),ans[i].end());
cout<<" "<<ans[i];
}
cout<<endl;
}
}
//
CF898B
枚举 (x) ,二分 ((n - a imes x) mod b) 是否等于 0
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n,a,b;
cin>>n>>a>>b;
for(int i=0;i<=n/a;i++)
if((n - i * a) % b == 0)
{
cout<<"YES"<<endl;
cout<<i<<' '<<(n - a * i) / b;
return 0;
}
cout<<"NO";
return 0;
}
//
CF877E
用(dfs)序来找到子树,一个子树作为一段来建线段树
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
struct Tree
{
int l,r;
int turn;
int sum;
int mid;
} tr[N * 4];
vector<int> g[N];//存图
int in[N],out[N],order[N],times = 0;// 进入栈的时间,出栈的时间,dfs序,当前时间
void dfs(int root,int father)
{
in[root] = ++times;
order[times] = root;
int len = g[root].size();
for(int i=0; i<len; i++)
{
int v = g[root][i];
if(v == father) continue;
dfs(v,root);
}
out[root] = times;
}
void pushup(int u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void pushdown(int u)
{
if(tr[u].turn)
{
tr[u<<1].turn ^= 1, tr[u<<1|1].turn ^= 1;
tr[u<<1].sum = tr[u<<1].r - tr[u<<1].l + 1 - tr[u<<1].sum;// xor
tr[u<<1|1].sum = tr[u<<1|1].r - tr[u<<1|1].l + 1 - tr[u<<1|1].sum;// xor
tr[u].turn = 0;
}
}
int w[N];//原开关情况
void build(int u,int l,int r)
{
if(l == r) tr[u].l = l,tr[u].r = r,tr[u].turn = 0,tr[u].sum = w[order[l]];
else
{
tr[u].l = l,tr[u].r = r,tr[u].turn = 0;
int mid = l + r >> 1;
tr[u].mid = mid;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
}
void modify(int u,int l,int r)
{
if(tr[u].l >= l && tr[u].r <= r)
{
tr[u].sum = tr[u].r - tr[u].l + 1 - tr[u].sum; // xor
tr[u].turn ^= 1;
}
else
{
pushdown(u);
if(l <= tr[u].mid) modify(u<<1,l,r);
if(r > tr[u].mid) modify(u<<1|1,l,r);
pushup(u);
}
}
int query(int u,int l,int r)
{
if(tr[u].r < l || tr[u].l > r) return 0;
if(tr[u].l >= l && r >= tr[u].r) return tr[u].sum;
pushdown(u);
int res = 0;
if(l <= tr[u].mid) res += query(u<<1,l,r);
if(r > tr[u].mid) res += query(u<<1|1,l,r);
pushup(u);
return res;
}
int main()
{
int n;
cin>>n;
for(int i=2; i<=n; i++)
{
int x;
scanf("%d",&x);
g[x].push_back(i);
g[i].push_back(x);
}
for(int i=1; i<=n; i++) scanf("%d",&w[i]);
dfs(1,-1);
build(1,1,n);
int q;
scanf("%d",&q);
while(q--)
{
char opt[4];
int x;
scanf("%s%d",opt,&x);
if(opt[0] == 'p') modify(1,in[x],out[x]);
else cout << query(1,in[x],out[x]) << endl;
}
return 0;
}
//
CF787B
如果一个团队中没有出现绝对值相同的两个数,就是YES,否则NO
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 1e4+10;
unordered_map<int,int> t;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int k;
cin>>k;
t.clear();
bool flag = 0;
for(int i=1;i<=k;i++)
{
int x;
cin>>x;
t[x] = 1;
if(t[-x])
{
flag = 1;
}
}
if(!flag)
{
cout<<"YES";
return 0;
}
}
cout<<"NO";
return 0;
}
//
CF776B
质数为1,否则为2
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
bool st[N];
int prime[N],cnt=0;
void gets_prime(int n)
{
for(int i=2;i<=n;i++)
{
if(!st[i]) prime[cnt++] = i;
for(int j=0;prime[j] <= n/i;j++)
{
st[prime[j] * i] = 1;
if(i % prime[j] == 0) break;
}
}
return ;
}
int main()
{
int n;
cin>>n;
gets_prime(n+2);
if(n < 3) cout<<1<<endl;
else cout<<2<<endl;
for(int i=2;i<=n+1;i++)
{
if(st[i]) cout<<2<<' ';
else cout<<1<<' ';
}
return 0;
}
CF734C
考虑不用药,(ans = n * w)
考虑只用第一种药,如果(b[i]le s),就更新答案 (ans = min(ans,n * a[i]))
考虑只用第二种药,如果(d[i]le s),就更新答案 (ans = min(ans,(n-c[i])))
考虑先用第一种药,再在d中二分出 (x) 为 (s - b[i]) 的位置, (ans = min(ans, (n-c[x]) * a[i])
#include <bits/stdc++.h>
using namespace std;
const int INF= 0x3f3f3f3f;
const int N=2e5+5;
typedef long long LL;
LL n,m,k,w,s;
LL b[N],c[N];
struct Node
{
LL x;
LL y;
} a[N];
int main()
{
scanf("%d%d%d%d%d",&n,&m,&k,&w,&s);
for(int i=1; i<=m; i++) scanf("%d",&a[i].x);
for(int i=1; i<=m; i++) scanf("%d",&a[i].y);
for(int i=1; i<=k; i++) scanf("%d",&b[i]);
for(int i=1; i<=k; i++) scanf("%d",&c[i]);
LL time=n*w;
for(int i=1; i<=k; i++)
{
if(c[i] <= s)
{
time=min(time, (n-b[i])*w );
}
}
for(int i=1; i<=m; i++)
{
if(a[i].y <= s)
{
time=min(time, n*a[i].x );
}
}
for(int i=1; i<=m; i++)
{
if(a[i].y > s) continue;
LL aa=upper_bound(c+1,c+1+k, s-a[i].y )-(c+1);
if(c[aa] <= s-a[i].y)
time=min(time, (n-b[aa])*a[i].x) ;
}
cout<<time;
return 0;
}
CF898A
将一个数四舍五入。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
cin>>n;
int a = n % 10;
int b = 10 - (n % 10);
if(a < b) cout<<n - a;
else cout<< n + b;
return 0;
}
//
CF811A
模拟,实在没啥可以解释的
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
int k = 1;
while(1)
{
if(a < k)
{
cout<<"Vladik"<<endl;
break;
}
a -= k;
k++;
if(b < k)
{
cout<<"Valera"<<endl;
break;
}
b -= k;
k ++;
}
return 0;
}
CF808A
所有的lucky year都可以表示为 (j * 10^i) ,枚举 (i) 和 (j) 即可。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=1;;i*=10)
{
bool flag = 0;
for(int j=1;j<=9;j++)
{
if(i * j > n)
{
cout<<i*j-n<<endl;
flag = 1;
break;
}
}
if(flag) break;
}
return 0;
}
CF787A
枚举时刻 (i), 当 ((i - b) mod a == 0 ; and ;(i - d) mod c == 0) 即输出i
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int a,b,c,d;
cin>>a>>b>>c>>d;
for(int i=0;i<=100000000;i++)
{
if(i-b >= 0 && i-d >= 0 && (i - b) % a == 0 && (i - d) % c == 0)
{
cout<<i;
return 0;
}
}
cout<<-1;
return 0;
}
//
CF786A
现在我们知道 1 是必败态,那么我们通过 (DFS) 可以判断每个点的胜负情况、是否有解。
我们考虑逆向思维,对每个玩家在 1 时的先手状态向前转移,具体过程如下:
- 定义 (DFS(v,now)) 表示现在是 (now)的位置,玩家 (v) 先手。
- 枚举上一次玩家 (u) 的操作 (x),那么可以从 (now-x) 的位置转移到 (now) 的位置(注意这里的 (now-x) 不能等于 (1))。
- 如果 (now) 的位置是必败态,那么根据结论:能转移到必败态的状态就是必胜态,可以得到 (now-x) 的位置是必胜态。
- 如果 (now) 的位置是必胜态,那么根据结论:只能转移到必胜态的状态就是必败态。我们记 (cnt_{u,i}) , (i) 表示在(i) 这个位置且 u 先手可以转移到的必胜态数量。当 (cnt_{u,now-x}+1=k_u),时,意味着从 ((u,now-x)) 转移到的所有状态都是必胜态,那么意味着从 ((u,now-x)) 这个状态为必败态。
- 继续 (DFS(u,now-x)) 进行转移即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 7005;
int k[2];
int cnt[2][N];
int step[2][N];
bool vis[2][N],win[2][N];
int n;
void dfs(int user,int pos)
{
if(vis[user][pos]) return ;
vis[user][pos] = 1;
int u = user ^ 1;
for(int i=1;i<=k[u];i++)
{
int pre = (pos - step[u][i] + n - 1) % n + 1;
if(pre == 1) continue;
if(!win[user][pos])
{
win[u][pre] = 1;
dfs(u,pre);
}
else if(++cnt[u][pre] == k[u])
{
win[u][pre] = 0;
dfs(u,pre);
}
}
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=0;i<=1;i++)
{
cin>>k[i];
for(int j=1;j<=k[i];j++)
cin>>step[i][j];
}
dfs(0,1);
dfs(1,1);
for(int i=0;i<=1;i++)
{
for(int j=2;j<=n;j++)
{
if(!vis[i][j]) cout<<"Loop ";
else if(win[i][j]) cout<<"Win ";
else cout<<"Lose ";
}
cout<<endl;
}
return 0;
}
//
CF701B
可以将车平移到四周,类似数学中的一块草地,要在上面铺路,求草地面积。
开个col,row数组记录这一列,行有没有被攻击。
如果新增的车的那一列,行没有攻击过,则n--,或m--
最后输出n * m
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
bool row[N];
bool col[N];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
long long num_row = n,num_col = n;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(!row[x]) row[x] = 1,num_row --;
if(!col[y]) col[y] = 1,num_col --;
cout<<num_row*num_col<<endl;
}
return 0;
}
//
CF701A
排序,a[i] 和 a[n - i + 1] 为一对
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
struct Node
{
int val;
int id;
bool operator < (const Node& x) const
{
return val < x.val;
}
}a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].val,a[i].id=i;
sort(a+1,a+1+n);
for(int i=1;i<=n/2;i++)
cout<<a[i].id<<' '<<a[n-i+1].id<<endl;
return 0;
}
CF664A
如果 a==b ,则为a,否则为1
#include <bits/stdc++.h>
using namespace std;
int main()
{
string a,b;
cin>>a>>b;
if(a==b) cout<<a;
else cout<<1;
return 0;
}
CF608B
处理出 b 的前缀和
如果a[i] == 1,就和b[i.i + n - 1],ans 加上b中以i为左端点,长度为m的区间内0的个数
反之亦然
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 200005;
char a[N],b[N];
int sum[N];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>a+1>>b+1;
int n = strlen(a + 1), m = strlen(b + 1);
for(int i=1;i<=m;i++) sum[i] = sum[i-1] + (b[i] == '0');
LL ans = 0;
for(int i=1;i<=n;i++)
{
if(a[i] == '1') ans += sum[m - (n - i)] - sum[i - 1];
else ans += m - n + i - sum[m - (n - i)] - i + 1 + sum[i-1];
}
cout<<ans;
return 0;
}
CF608A
记录从第i楼出发的乘客的到达时间的最大值
从上到下枚举楼层,如果当前这一层楼的所有乘客都到了。就直接下楼 —— ans++
否则就等到乘客到了位置,再下楼——ans = max(ans,f[i]) + 1
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 1005;
int n,s,x;
int f[N],t[N];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>s;
for(int i=1;i<=n;i++) cin>>x>>t[i],f[x] = max(f[x],t[i]);
int ans = 0;
for(int i=s;i>=1;i--)
{
ans = max(ans,f[i]);
ans ++;
}
cout<<ans;
return 0;
}
//
CF606B
阅读题
按照给出的序列走,问第k次走到的点在之前是否走过,并问最后的时候有多少个点没有走过
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 5005;
int n,m;
int x,y;
string s;
bool st[N][N];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m>>x>>y;
cin>>s;
int len = s.size(), cnt = 1;
st[x][y] = 1;
cout<<1<<' ';
for(int i=0;i<len-1;i++)
{
if(s[i] == 'U' && x > 1) x--;
if(s[i] == 'D' && x < n) x ++;
if(s[i] == 'L' && y > 1) y --;
if(s[i] == 'R' && y < m) y ++;
if(!st[x][y]) cout<<1<<' ',cnt++;
else cout<<0<<' ';
st[x][y] = 1;
}
cout << n * m - cnt;
return 0;
}
//
CF606A
每两个同色剩余可以换一个欠的
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int a[5],b[5],c[5];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n = 3;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
int add = 0,sub = 0;
for(int i=1;i<=n;i++) c[i] = a[i] - b[i];
for(int i=1;i<=n;i++)
{
if(c[i] < 0) sub += c[i];
if(c[i] > 0) add += c[i] / 2;
}
// cout<<add<<' '<<sub<<endl;
if(add + sub >= 0) cout<<"Yes";
else cout<<"No";
return 0;
}
//
CF554B
如果这两行是一样的,整列翻转只有长的也一样
#include <bits/stdc++.h>
using namespace std;
unordered_map<string,int> h;
string s;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>s,h[s]++;
int res = 0;
for(auto x : h)
res = max(res,x.second);
cout<<res;
return 0;
}
CF456B
((1^n + 2^n + 3^n + 4^n) mod 5 = (1^n mod 5 + 2^n mod 5 + 3^n mod 5 + 4^n mod 5) mod 5)
根据费马小定理:(a^{5-1} equiv 1 (mod ;5))
所以原式 $ = (1^{n; mod;4} + 2^{n; mod;4} + 3^{n; mod;4} + 4^{n; mod;4}) mod 5$
最后打个高精模吗,搞定
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int mod(string a,int b)//高精度a除以单精度b
{
int d=0;
for(int i=0;i<a.size();i++) d=(d*10+(a[i]-'0'))%b; //求出余数
return d;
}
int power(int x,int y)
{
int ans = 1;
for(int i=1;i<=y;i++) ans *= x;
return ans;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
string n;
cin>>n;
int mi = mod(n,4);
LL ans = (power(2,mi) % 5 + power(3,mi) % 5 + power(4,mi) + 1) % 5;
cout<<ans;
return 0;
}
//
CF456A
按价格排序,维护质量前缀最大值,发现前缀最大值比 (b_i) 大,就Happy,反之亦然
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 1e5;
PII a[N];
int n;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i].first>>a[i].second;
sort(a+1,a+1+n);
for(int i=1;i<n;i++)
{
if(a[i].first < a[i+1].first && a[i].second > a[i+1].second)
{
cout<<"Happy Alex";
return 0;
}
}
cout<<"Poor Alex";
return 0;
}
//
CF455B
判断前缀可以用Trie解决
如果根节点有必胜策略,也有必败策略,则倒数第二局必败的就可以在最后一局必胜,如此类推,第一局的先手必胜
如果根节点有必胜策略,没有必败策略,则如果局数为奇数,第一局的先手必胜,否则必败
如果根节点没有必胜策略,但有必败策略,那么每一局都是后手胜利,所以最后是后手胜利
求出所有点是否有必胜态和必败态,最后根据上面的几种情况求出答案
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 1e6 + 10;
int trie[N][26],cnt;
int sg[N];//1 win, 2 lose, 3 up to you, 4 not sure
int n, m;
void insert(string s)
{
int u = 0, len = s.size();
for(int i=0;i<len;i++)
{
int v = s[i] - 'a';
if(!trie[u][v]) trie[u][v] = ++cnt;
u = trie[u][v];
}
}
void dfs(int u)
{
bool win = 0;
bool lose = 0;
bool flag = 1;//是否为前缀
for(int i=0;i<26;i++)
{
if(trie[u][i])
{
dfs(trie[u][i]);
if(sg[trie[u][i]]==1||sg[trie[u][i]]==4)
win=1;
if(sg[trie[u][i]]==2||sg[trie[u][i]]==4)
lose=1;
flag=0;
}
if(flag) sg[u] = 1;
else
{
if(win && lose) sg[u] = 3;
else if(win) sg[u] = 2;
else if(lose) sg[u] = 1;
else sg[u] = 4;
}
}
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
insert(s);
}
dfs(0);
if(sg[0]==1) puts("Second");
else if(sg[0]==2)
if(m&1) puts("First");
else puts("Second");
else if(sg[0]==3) puts("First");
else puts("Second");
return 0;
}
CF455A
DP
(f[i]) 为删数值为 i 时的最大价值,桶 t[i] 为数值为 (i) 的数出现的次数
如果 (f[i]) 是被 (i-1) 通过 ((i-1)+1) 被删的,价值为 (f[i-1])
否则不删 (i-1) 的话一定会删 (i) 和 (i-2) (否则就一定不是最佳答案)价值为 f[i-2] + i * t[i]
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PII;
const double PI = 3.1415926535;
const LL Mod = 1e9 + 7;
const LL INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const LL dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const LL dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const LL pow10[15] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
const LL N = 1e5 + 10;
int n, a[N];
LL dp[N];
int main()
{
cin >> n;
while (n--)
{
int x;
cin >> x;
a[x]++;
}
for (int i = 1; i <= 100000; i++)
{
if (a[i]) dp[i] = dp[i - 2] + 1ll * a[i] * i;
dp[i] = max(dp[i], dp[i - 1]);
}
cout << dp[100000];
return 0;
}
CF454B
找到最大的值所在的位置,如果最大值在最后一位,就是不需要移动
最大值的位置++则为理论最小值的位置,再向后找比他大的,如果最后的指针不在n-1处,或者最后一位比第一位要大,就是不合法的,否则合法
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
const int N = 1e5 + 10;
int a[N];
int main()
{
int n;
cin >> n;
for (int i = 0; i <= n - 1; ++i)
cin >> a[i];
int i = 0, j = 0;
while (a[i] <= a[i + 1])
++i;
if (i == n - 1)
{
cout << 0;
return 0;
}
++i;
++j;
while (a[i] <= a[i + 1])
{
++i;
++j;
}
if (i != n - 1)
{
cout << -1;
return 0;
}
else if (a[n - 1] > a[0])
{
cout << -1;
return 0;
}
else
cout << j;
return 0;
}
//
CF454A
直接模拟
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n/2;i++)
{
for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
for(int j=0;j<i*2+1;j++) cout<<'D';
for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
cout<<endl;
}
for(int i=1;i<=n;i++) cout<<'D';
cout<<endl;
for(int i=n/2-1;i>=0;i--)
{
for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
for(int j=0;j<i*2+1;j++) cout<<'D';
for(int j=0;j<(n-i*2+1)/2-1;j++) cout<<'*';
cout<<endl;
}
return 0;
}
//
CF453A
期望 = 概率 * 权值
如果投 n 次,最大点数为 i
如果 n 次投的点数在1~k中,共有 (k^n) 种情况
如果 n 次投的点数在1~k-1中,共有 ((k-1)^n) 种情况
这 n 次投掷中有 k 的有 (k^n - (k-1)^n) 种情况,概率为(frac{k^n - (k-1)^n}{k^n})
最后的期望$ = frac{sum_{i=1}^{m} i imes (i^n - (i-1)n)}{mn} $
#include<cstdio>
#include<cmath>
using namespace std;
double n,m,ans;
int main(){
scanf("%lf%lf",&m,&n);
for(double i=1;i<=m;i++)
ans+=i*(pow(i/m,n)-pow((i-1)/m,n));
printf("%.12lf
",ans);
}
CF45A
输出 (当前月份 + n) % 12 的月份
#include <bits/stdc++.h>
using namespace std;
string month[13]={"January","February","March","April","May","June","July","August","September","October","November","December"};
int get(string str)
{
for(int i=0;i<12;i++) if(month[i]==str) return i;
}
string to_str(int i)
{
return month[i];
}
int main()
{
string str;
int n;
cin>>str>>n;
int start=get(str);
int ans=(start+n)%12;
cout<<to_str(ans);
return 0;
}
CF20C
无向图最短路径,直接dijkstra+记录路径,递归输出
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PII;
const double PI = 3.1415926535;
const LL Mod = 1e9 + 7;
const LL INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const LL dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const LL dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const LL pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const LL N = 1e5 + 10;
struct Edge
{
LL v,w,nxt;
}e[N * 2];
LL head[N];
priority_queue<PII,vector<PII>,greater<PII>> h;
LL n,m;
LL idx = 0;
void add(LL u,LL v,LL w)
{
e[++idx].v = v;
e[idx].w = w;
e[idx].nxt = head[u];
head[u] = idx;
}
bool st[N];
LL dis[N];
LL pre[N];
LL dijkstra(LL start,LL dest)
{
memset(dis,0x3f,sizeof dis);
dis[start] = 0;
h.push({0,1});
while(!h.empty())
{
LL u = h.top().second,disu = h.top().first;
h.pop();
if(st[u]) continue;
st[u] = 1;
for(LL j=head[u];j;j=e[j].nxt)
{
LL v = e[j].v, w = e[j].w;
if(dis[v] > disu + w)
{
dis[v] = disu + w;
pre[v] = u;
h.push({dis[v],v});
}
}
}
return dis[dest];
}
void dfs(LL t, LL x, LL cnt)
{ //当前点x到起点t的最短路径
if (pre[x] != 0)
{
dfs(t, pre[x], cnt + 1);
printf("%lld%c", x, cnt == 1 ? '
' : ' ');
}
else printf("%lld%c", t, ' ');
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(LL i=1;i<=m;i++)
{
LL u,v,w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
LL ans = dijkstra(1,n);
if(ans == LNF) cout<<-1;
else dfs(1,n,1);
return 0;
}
//
CF9A
概率论,取两人的最大值max, 答案为 (frac{6 - max }{6})
最后上下同除gcd
#include <iostream>
using namespace std;
int main()
{
int a,b,c;
cin>>a>>b;
c=max(a,b);
if(c==1)
cout<<"1/1"; //一定能赢
if(c==6)
cout<<"1/6";
if(c==5)
cout<<"1/3";
if(c==4)
cout<<"1/2";
if(c==3)
cout<<"2/3";
if(c==2)
cout<<"5/6";
return 0;
}
CF4A
所有大于4的偶数都可以
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int main()
{
int n;
cin>>n;
if(n%2==0&&n!=2)
{
cout<<"YES";
return 0;
}
cout<<"NO";
return 0;
}
CF2A
开个map维护信息
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 1005;
map<string,int> hash_map;//哈希表
int n;
string name[N];//名字
int sorce[N];//分数
map<string,int> temp;//统计谁先到达最大分数的时候用的
int main()
{
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>name[i]>>sorce[i];
hash_map[name[i]] += sorce[i];
}
int maxx = -0x3f3f3f3f;
for(int i=1;i<=n;i++) maxx = max(maxx,hash_map[name[i]]);
for(int i=1;i<=n;i++)
{
temp[name[i]] += sorce[i];
if(temp[name[i]] >= maxx && hash_map[name[i]] == maxx)
{
cout<<name[i]<<endl;
return 0;
}
}
return 0;
}
CF1A
求长和宽除以a上取整,相乘
#include <iostream>
using namespace std;
int main()
{
long long a,m,n;
cin>>n>>m>>a;
cout<<((n-1)/a+1)*((m-1)/a+1);
return 0;
}
CF954B
枚举复制串的长度,判断是否可以复制,可以就更新答案
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
char s[105];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
scanf("%d%s",&n,s+1);
int ans = n;
for(int i=1;i<=n/2;i++)
{
bool flag = 0;
for(int j=i+1;j<=i+i;j++)
{
if(s[j-i] != s[j])
{
flag = 1;
break;
}
}
if(!flag) ans = min(ans, n - i + 1);
}
cout<<ans;
return 0;
}
//
CF954A
贪心,遇到 RU 或 UR 就换成 D
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
string a;
cin>>n>>a;
a += ' ';
int ans = 0;
for(int i=0;i<a.size()-1;i++)
{
if(a[i] == 'R' && a[i+1] == 'U') ans ++,i++;
else if(a[i] == 'U' && a[i+1] == 'R') ans ++,i++;
else ans ++;
}
cout<<ans;
return 0;
}
//
CF1005B
求最长公共后缀
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int N = 0;
int main()
{
ios::sync_with_stdio(0);
string s,t;
cin>>s>>t;
int i=s.size()-1,j=t.size()-1;
for(;i>=0 && j >=0;i--,j--)
{
if(s[i] != t[j])
{
cout<<i+j+2;
return 0;
}
}
cout<<i+j+2;
return 0;
}
//
CF1005A
找1,长度为下一个 1 的位置减去当前 1 的位置
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int N = 1005;
int a[N];
vector<int> len;
int main()
{
ios::sync_with_stdio(0);
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
int suc = i;
while(suc<n && a[suc] < a[suc+1]) suc++;
len.push_back(suc - i + 1);
i = suc;
}
cout<<len.size()<<endl;
for(int i=0;i<len.size();i++) cout<<len[i]<<' ';
return 0;
}
//
CF1009B
贪心,将所有 1 插入到第一个 2 的前面
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 0;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
string s,ans;
cin>>s;
int n = s.size(), cnt = 0;
for(int i=0;i<n;i++)
if(s[i] == '1') cnt++;
else ans += s[i];
n = ans.size();
int pos = n;
for(int i=0;i<n;i++)
if(ans[i] != '0')
{
pos = i;
break;
}
ans.insert(pos,string(cnt,'1'));
cout<<ans;
return 0;
}
//
CF1009A
扫一遍数组,能买就买
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double PI = 3.1415926535;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f3f3f;
const int dx4[5] = {0, 1, 0, -1}, dy4[5] = {1, 0, -1, 0};
const int dx8[10] = {0, 1, 1, 1, 0, -1, -1, -1}, dy8[10] = {1, 1, 0, -1, -1, -1, 0, 1};
const int pow10[15] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
const int N = 1005;
int a[N];
int b[N];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
int ans = 0;
for(int i=1,j=1;i<=n&&j<=m;i++)
{
if(a[i] <= b[j]) j ++, ans ++;
}
cout<<ans;
return 0;
}
//
CF1076A
找到第一个波峰,把它删掉
#include <bits/stdc++.h>
using namespace std;
const int N = 2*1e5+10;
int n;
char str[N];
int main()
{
cin>>n>>str;
for(int i=0;i<n;i++)
if(i == n-1)
{
str[i] = 0;
puts(str);
break;
}
else if(str[i] > str[i+1])
{
str[i] = 0;
printf("%s%s
",str,str+i+1);
break;
}
return 0;
}
CF1092A
输出 $ lfloor n / k floor $ 个a, $ lfloor n / k floor $ 个b, $ lfloor n / k floor $ 个c ... 最后输出 $ lfloor n / k floor + n mod k$ 个a
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
int times = n/k;
string str;
for(int i=0;i<k;i++)
for(int j=1;j<=times;j++)
{
str += 'a' + i;
}
for(int i=1;i<=n - k * times;i++) str += 'a';
cout<<str<<endl;
}
return 0;
}
CF1099B
尽可能拼成正方形,枚举宽度,算长度
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int minn = 0x3f3f3f3f;
for(int i=1;i<=(n+i-1)/i;i++)
{
minn = min(minn,i+(n+i-1)/i);
}
cout<<minn<<endl;
}
CF1105A
排序,枚举t,计算距离,得出答案
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int w[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i];
sort(w+1,w+n+1);
int pos,minn = 0x3f3f3f3f;
for(int i=1;i<=1000;i++)
{
int dis = 0;
for(int j=1;j<=n;j++)
dis += max(abs(i-w[j])-1,0);
if(dis < minn) minn = dis,pos = i;
}
cout<<pos<<' '<<minn<<endl;
return 0;
}
CF1141B
破环成链,暴力扫一遍
#include <bits/stdc++.h>
using namespace std;
const int N = 400005;
int w[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i],w[i+n] = w[i];
int suc = 0,maxx = 0;
for(int i=1;i<=2*n;i++)
if(w[i]) suc ++;
else maxx = max(maxx,suc), suc = 0;
cout<<maxx<<endl;
}
CF1304B
开个set,把所有串塞进去
枚举所有串,如果他的 reverse 在set里,就把它的reverse删掉
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
string str[N];
vector<string> l,r;
string mid;
set<string> dirt;
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>str[i],dirt.insert(str[i]);
for(int i=1;i<=n;i++)
{
string t = str[i];
reverse(t.begin(),t.end());
if(t == str[i]) mid = str[i];
else if(dirt.find(t) != dirt.end())
{
l.push_back(t);
r.push_back(str[i]);
dirt.erase(t);
dirt.erase(str[i]);
}
}
cout<<l.size() * m + r.size() * m + mid.size()<<endl;
for(int i=l.size()-1;i>=0;i--) cout<<l[i];
cout<<mid;
for(int i=0;i<r.size();i++) cout<<r[i];
return 0;
}
CF1304A
如果 (y - x ) % (a + b) == 0,答案为 (y - x ) / (a + b)
否则为-1
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int x,y,a,b;
cin>>x>>y>>a>>b;
if((y-x)%(a+b) == 0) cout<<(y-x)/(a+b);
else cout<<-1;
cout<<endl;
}
return 0;
}//
CF1313B
最高为 x+y-n , 最低为 x + y - 1
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,x,y;
cin >> n >> x >> y;
int maxx = min(max(x + y + 1 - n , 1), n);
int minn = min(x + y - 1, n);
cout << maxx << ' ' << minn << endl;
}
return 0;
}
//
CF1313A
因为每种最多只能提供一份,所以最多只有 7 种情况,只需要判断这 7 种情况是否都可行就可以了
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
int f[N][N][N];
int cost[10][3] = {{1,0,0},{0,1,0},{0,0,1},{1,0,1},{1,1,0},{0,1,1},{1,1,1}};
int main()
{
ios::sync_with_stdio(0);
int t;
cin>>t;
while(t--)
{
memset(f,0,sizeof f);
int a, b, c;
cin >> a >> b >> c;
for(int i=0;i<7;i++)
for(int j=a;j>=cost[i][0];j--)
for(int k=b;k>=cost[i][1];k--)
for(int l=c;l>=cost[i][2];l--)
f[j][k][l] = max(f[j][k][l],f[j-cost[i][0]][k-cost[i][1]][l-cost[i][2]] + 1);
cout<<f[a][b][c]<<endl;
}
return 0;
}
//
CF1395A
细节题
如果(r,g,b,w) 中有三个以上为偶数,则为yes
如果(r,g,b,w) 中有两个为偶数,则为no
如果(r,g,b) 中有一个为0,则为no
其他都为yes
#include <bits/stdc++.h>
using namespace std;
long long n;
int main()
{
scanf("%lld",&n);
while(n--)
{
long long r,g,b,w;
scanf("%lld%lld%lld%lld",&r,&g,&b,&w);
int cnt=0;
if(r%2==0) cnt++;
if(g%2==0) cnt++;
if(b%2==0) cnt++;
if(w%2==0) cnt++;
if(cnt>=3) puts("Yes");
if(!r || !g || !b) puts("No");
else if(cnt == 2) puts("No");
else puts("Yes");
}
return 0;
}
CF1392D
唯一的不符合条件的情况是有连续的 3 个相同的字符(A打B,B打C,C打D)
破环成链,统计连续字符的个数,每一段连续对答案的贡献为 长度 / 3
细节:对于所有字符都相同的要特判,答案为((n + 2)/3)
#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 10;
char s[N];
int n;
bool same()
{
for(int i=2; i<=n; i++)
if(s[i] != s[1])
return 0;
return 1;
}
void solve()
{
cin>>n>>s+1;
if(same())
{
cout << (n - 1) / 3 + 1<<endl;
return ;
}
int pos = 0;
for(int i=1; i<=n; i++) // find the legal braek point
if(s[i] != s[n])
{
pos = i - 1;
break;
}
for(int i=1; i<=n; i++) s[i+n] = s[i];
for(int i=1; i<=n; i++) s[i] = s[i + pos];
int ans = 0,suc = 0;
for(int i=1; i<=n; i++)
{
if(s[i] != s[i - 1]) ans += suc / 3, suc = 0;
suc ++;
}
ans += suc / 3;
cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
return 0;
}