裂开昨晚差个E ak了,赛后居然又做出来了裂开
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
const long long inf=1e17;
int n,m,k;
void solve()
{
char a;
int x;
cin>>a>>x;
for(int i=1;i<=8;i++){
if(i==x) continue;
cout<<a<<i<<"\n";
}
for(char i='a';i<='h';i++){
if(i==a) continue;
cout<<i<<x<<"\n";
}
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
我是直接拿两个栈模拟的,一个放小写一个放大写最后根据位置输出
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<char, int> PII;
const long long inf=1e17;
int n,m,k;
int l[N],r[N];
void solve()
{
string s;
cin>>s;
vector<PII> st1,st2;
for(int i=0;i<s.size();i++){
if(s[i]=='b'){
if(st1.empty()) continue;
else st1.pop_back();
}
else if(s[i]=='B'){
if(st2.empty()) continue;
else st2.pop_back();
}
else if(islower(s[i])){
st1.push_back({s[i],i});
}
else st2.push_back({s[i],i});
}
int idx1=0,idx2=0;
while(idx1<st1.size()&&idx2<st2.size()){
if(st1[idx1].second<st2[idx2].second){
cout<<st1[idx1].first;
idx1++;
}
else{
cout<<st2[idx2].first;
idx2++;
}
}
while(idx1<st1.size()){
cout<<st1[idx1].first;
idx1++;
}
while(idx2<st2.size()){
cout<<st2[idx2].first;
idx2++;
}
cout<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
C:
直觉题....
我也不知道为啥看了个题就直接觉得跟最大值有关...,可能每天刷一场cf刷多了,直觉就来了....
可以手玩发现如果最大值很大,那么全都去消掉最大值,否则肯定能互相消完,特判奇数
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
const long long inf=1e17;
int n,m,k;
int l[N],r[N];
void solve()
{
cin>>n;
string s;
cin>>s;
map<char,int> mp;
for(auto x:s) mp[x]++;
int mx=0;
for(auto [k,v]:mp){
mx=max(mx,v);
}
int res=0;
if(n%2==1) res=1;
if(n-mx>=mx) mx=0;
else mx=mx-(n-mx);
cout<<max(res,mx)<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
对就是这个题,我做了一个小时,然后F+G也才用了一个小时
首先K肯定有单调性可以二分,难点是如何check
我是这样想的他不是每次可以移动0-k距离吗
然后我直接维护一个可达区间,如果当前区间在这个可达区间右侧,那我最右边可以直接拉曼跳到right+k,左区间可以往左边跳,另一个同理
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
const long long inf=1e17;
int n,m,k;
int l[N],r[N];
void solve()
{
cin>>n;
l[0]=r[0]=0;
for(int i=1;i<=n;i++){
cin>>l[i]>>r[i];
}
int res=0;
auto check=[&](int k)
{
int left=0,right=0;
for(int i=1;i<=n;i++)
{
if(r[i]>=right)
{
if(right+k>=l[i])
{
left=max(left-k,l[i]);
right=min(right+k,r[i]);
}
else return false;
}
else
{
if(left-k<=r[i])
{
left=max(left-k,l[i]);
right=min(right+k,r[i]);
}else return false;
}
}
return true;
};
int ll=0,rr=1e9;
while(ll<rr){
int mid=ll+rr>>1;
if(check(mid)) rr=mid;
else ll=mid+1;
}
cout<<ll<<"\n";
// cout<<res<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
可以发现每一位是独立的,然后n最多7位
直接枚举a b c是哪些数即可,然后乘法原理
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
const long long inf=1e17;
int n,m,k;
int a[N];
string s;
int res=0;
void solve()
{
cin>>n;
int res=0;
s=to_string(n);n=s.size();
for(int i=0;i<n;i++)
{
int cnt=0;
for(int a=0;a<=9;a++){
for(int b=0;b<=9;b++){
for(int k=0;k<=9;k++){
if(a+b+k==(s[i]-'0')) cnt++;
}
}
}
if(res==0) res=cnt;
else res*=cnt;
}
cout<<res<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
首先手完题老规矩
先想操作有啥性质
对于第一个操作等于整体区间往右移动 (如果先翻转则变成向左移动)
第二个操作就是可以让整个递减区间变成递增
然后我们直接拉环成链
如果存在一个区间长度为n那么就是可以通过右移变成一个递增或者递减的序列
然后计算次数即可
我get函数里面 f维护的就是递增连续个数,g是递减连续
然后枚举向左移动还是向右移动,分别计算递增和递减所需要的最小次数即可
然后因为可以翻转,我们可以直接把整个数组翻转再求一编减少代码量
计算次数的话就交给读者自己画图算咯
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
const long long inf=1e17;
int n,m,k;
int a[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int res=2e18;
auto get=[&](int v){
vector<int> f(n*2+10);
for(int i=1;i<=n;i++)
{
if(a[i]>=a[i-1]) f[i]=f[i-1]+1;
else f[i]=1;
}
if(f[n]==n){
res=min(res,v+0ll);
}
for(int i=n+1;i<=n+n;i++)
{
a[i]=a[i-n];
if(a[i]>=a[i-1]) f[i]=f[i-1]+1;
else f[i]=1;
if(f[i]==n)
{
res=min(res,v+n-(i-n));
}
}
vector<int> g(n*2+10);
g[1]=1;
for(int i=2;i<=n;i++){
if(a[i-1]>=a[i]) g[i]=g[i-1]+1;
else g[i]=1;
}
if(g[n]==n){
res=min(res,v+1ll);
}
for(int i=n+1;i<=n+n;i++){
if(a[i-1]>=a[i]) g[i]=g[i-1]+1;
else g[i]=1;
if(g[i]==n) res=min(res,v+1+n-(i-n));
}
};
get(0);
reverse(a+1,a+1+n);
get(1);
if(res==2e18) res=-1;
cout<<res<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}
正常套路题
n点n边,这是一个基环树
然后我习惯两个算法
1.建立反向边,然后直接从环开始dfs,
2.正常建边,拓扑排序删掉叶子节点,留下环,再单独处理环
因为要顺便记录操作所以我选的是2
然后拓扑排序剩下一些环
然后问题变成环里面求最小次数
正常是套路是随便选一个点dp当前点选还是不选
但是注意到,如果当前点是亮的,一定要改变他,所以我们直接贪心即可
所以我们直接枚举当前点改变或者不改变即可
我的dfs函数是记录原本这个环每个点的拓扑排序后的灯状态
因为这两个枚举都要用到原本灯状态,所以我直接懒狗,写了个dfs函数来记录到map里面了
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair<int, int> PII;
const long long inf=1e17;
int n,m,k;
int a[N];
vector<int> g[N];
void solve()
{
cin>>n;
string s;cin>>s;
s="?"+s;
for(int i=1;i<=n;i++) g[i].clear();
vector<int> d(n+10);
for(int i=1;i<=n;i++){
int x;cin>>x;
if(s[i]=='1') a[i]=1;
else a[i]=0;
g[i].push_back(x);
d[x]++;
}
vector<int> res;
queue<PII> q;
for(int i=1;i<=n;i++)
if(d[i]==0)
{
if(a[i]==1)
{
res.push_back(i);
a[i]=0;
q.emplace(i,1);
}
else q.emplace(i,0);
}
vector<bool> st(n+10);
while(q.size()){
auto t=q.front();
q.pop();
st[t.first]=true;
for(auto v:g[t.first])
{
a[v]^=t.second;
if(--d[v]==0)
{
if(a[v]==0) q.emplace(v,0);
else
{
res.push_back(v);
q.emplace(v,1);
}
a[v]=0;
}
}
}
map<int,int> mp;
function<void(int)> dfs=[&](int u){
if(st[u]) return ;
mp[u]=a[u];
st[u]=true;
for(auto v:g[u]) dfs(v);
st[u]=false;
};
for(int i=1;i<=n;i++){
if(st[i]) continue;
vector<int> d1,d2;
mp.clear();
int u=i;
dfs(u);
d1.push_back(u);
mp[u]^=1;mp[g[u][0]]^=1;
u=g[u][0];
while(u!=i)
{
if(mp[u]){
d1.push_back(u);
mp[u]^=1;
mp[g[u][0]]^=1;
}
u=g[u][0];
}
if(mp[u]==1){
cout<<-1<<"\n";return ;
}
mp.clear();
dfs(u);
u=g[u][0];
st[i]=true;
while(u!=i)
{
st[u]=true;
if(mp[u])
{
d2.push_back(u);
mp[u]^=1;
mp[g[u][0]]^=1;
}
u=g[u][0];
}
if(mp[i]==1){
cout<<"-1\n";return ;
}
if(d1.size()>d2.size()) swap(d1,d2);
for(auto x:d1) res.push_back(x);
}
cout<<res.size()<<"\n";
for(auto x:res) cout<<x<<" ";
cout<<"\n";
}
signed main()
{
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t=1;
cin>>t;
while(t--) solve();
}