A水题
乱搞
#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
int main()
{
int T;cin>>T;
while(T--)
{
int n;cin>>n;
ll ans=0;
for(int i=1;i<=n;++i)
{
int d;cin>>d;
ans+=d;
}
cout<<(ans+n-1)/n<<endl;
}
return 0;
}
B简单模拟
模拟
#include<iostream>
#include<map>
#include<vector>
using namespace std;
map<int,int>mp;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,k;cin>>n>>k;
int l=1,r=0;
vector<int>arr(n+10,0);
while(n--)
{
int d;cin>>d;
if(!mp[d])
{
arr[++r] = d;
mp[d]=1;
if(r-l+1>k)
{
mp[arr[l]]=0;
l++;
}
}
}
cout<<r-l+1<<endl;
for(int i=r;i>=l;--i)
cout<<arr[i]<<" ";
return 0;
}
C 成为马里奥
简单dfs,wa了三次
一次是上下来回横跳卡死了
第二第三次数组开小了,第一次越界开大了十倍,第二次交了发现还是少了一倍,简直智障
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char s[2][200100];
int n;
bool ok;
void dfs(int x,int y,int pre)
{
//cout<<x<<" "<<y<<endl;
if(x==1 && y==n) ok=1;
if(y>n || ok)return;
if(s[x][y]<='2' && pre == 1)
dfs(x,y+1,1);
else
{
if(s[x][y]<='2' && pre==1)
dfs(x,y+1,1);
if(s[x][y]>'2' && pre==2)
dfs(x,y+1,1);
if(s[x][y]>'2' &&pre==1)
dfs(x^1,y,2);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
while(T--)
{
cin>>n;
cin>>s[0]>>s[1];
ok=0;
dfs(0,0,1);
if(ok)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
D 找不同
维护26颗线段树或树状数组就完了
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
char s[100010];
int a[26][100010];
int len;
int lb(int x){return x&(-x);}
void add(int z,int x,int d)
{
while(x<=len)
{
a[z][x]+=d;
x+=lb(x);
}
}
int qry(int z,int x)
{
int ret =0 ;
while(x)
{
ret+=a[z][x];
x-=lb(x);
}
return ret;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s;
len = strlen(s);
for(int i=1;i<=len;++i)
add(s[i-1]-'a',i,1);
int d;cin>>d;
while(d--)
{
int opt;cin>>opt;
if(opt==1)
{
int a;char c;cin>>a>>c;
add(s[a-1]-'a',a,-1);
add(c-'a',a,1);
s[a-1] = c;
}
else
{
int a,b;cin>>a>>b;
int ans =0;
for(int i=0;i<26;++i)
{
int d = qry(i,b)-qry(i,a-1);
if(d)
ans++;
}
cout<<ans<<endl;
}
}
return 0;
}
E 猜题意
看了很久才知道题在说什么
计算对于相邻两个对不同修改的贡献,用树状数组记录一下就完了
今天教大家一个演自己的全新操作
for(int i=1;i<=m;++i) cin>>arr[m];
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
const int N = 2e5+10;
ll arr[N],brr[N],u[N],cf[N];
ll cl(ll a,ll b)
{
if(a==b)return 0;
if(a<b)return abs(b-1)-abs(a-b);
return abs(b)-abs(a-b);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;cin>>n>>m;
ll ret=0;
for(int i=1;i<=m;++i)
{
cin>>arr[i];
if(i!=1)
ret += abs(arr[i]-arr[i-1]);
}
for(int i=1;i<m;++i)
{
ll mn = min(arr[i],arr[i+1]);
ll mx = max(arr[i],arr[i+1]);
if(mn+1>=mx)continue;
cf[mn+1]--;
cf[mx]++;
}
for(int i=1;i<=m;++i)
{
if(i>1)
u[arr[i]]+=cl(arr[i],arr[i-1]);
//cout<<i<<" "<<arr[i]<<" "<<arr[i+1]<<endl;
if(i<m)
u[arr[i]]+=cl(arr[i],arr[i+1]);
}
ll anx=0;
for(int i=1;i<=n;++i)
{
anx+=cf[i];
cout<<ret+anx+u[i]<<" ";
}
return 0;
}
F 旋转跳跃我闭着眼
状态压缩,记录a~t出现的状态,计算数组中所有出现过的状态,找出两个不重合的状态之和的最大值
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N = 2e6+10;
int dp[N];
char s[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s;
int len = strlen(s);
for(int i=0;i<len;++i)
{
int dd = 0;
for(int j=0;j<20&&i+j<len;j++)
{
if(dd&(1<<(s[i+j]-'a')))
break;
dd|=(1<<(s[i+j]-'a'));
dp[dd] = j+1;
}
}
//puts("0");
for(int i=0;i<(1<<20);++i)
for(int j=0;j<20;++j)
dp[i|(1<<j)]=max(dp[i|(1<<j)],dp[i]);
//puts("1");
int mx = 0;
for(int i=0;i<(1<<20);++i)
mx = max(mx,dp[i]+dp[i^((1<<20)-1)]);
cout<<mx<<endl;
return 0;
}