A
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
void slove(){
int m;
cin>>m;
int x=1;
while(m>=x*10){
x*=10;
}
m-=x;
cout<<m<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
cin>>T;
while(T--){
slove();
}
return 0;
}
B
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
void slove(){
string s;
cin>>s;
map<char,int>mp;
int sum=0,ans=0;
for(int i=0;i<s.length();i++){
mp[s[i]]++;
if(mp[s[i]]==1)sum++;
if(sum>3){
mp.clear();
mp[s[i]]=1;
sum=1;
ans++;
}
}
if(sum)ans++;
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
cin>>T;
while(T--){
slove();
}
return 0;
}
C
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
void slove(){
int n,k;
cin>>n>>k;
map<int,int>lt,rt;
for(int i=1;i<=n;i++){
int u;
cin>>u;
if(!lt.count(u))lt[u]=i,rt[u]=i;
else rt[u]=i;
}
for(int i=1;i<=k;i++){
int a,b;
cin>>a>>b;
if(!lt.count(a)||!lt.count(b))cout<<"NO\n";
else if(lt[a]>rt[b])cout<<"NO\n";
else cout<<"YES\n";
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
cin>>T;
while(T--){
slove();
}
return 0;
}
D
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
map<char,int>mp;
struct node{
int x;
int s;
int p;
}a[200005];
inline bool cmp1(node a,node b){
return a.s<b.s;
}
inline bool cmp2(node a,node b){
return a.x<b.x;
}
void slove(){
string s;
int n;
cin>>s>>n;
int sum=0;
int l=s.length();
for(int i=0;i<l;i++){
a[i]={i,mp[s[i]],0};
}
sort(a,a+l,cmp1);
for(int i=0;i<l;i++){
if(sum+a[i].s<=n){
sum+=a[i].s,a[i].p=1;
}
}
sort(a,a+l,cmp2);
for(int i=0;i<l;i++){
if(a[i].p)cout<<s[i];
}
cout<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
cin>>T;
int t=1;
char c='a';
for(t,c;t<=26;t++,c++){
mp[c]=t;
}
while(T--){
slove();
}
return 0;
}
E
题意
给出n个骨牌,每个骨牌上写有两个数字,问能否把骨牌分成两堆,使得每堆中不存在重复的数字.
思路
如果要刚好在分成2堆并且不存在重复数字,则需要满足:
1.每个数字出现的次数一定是2
2.把每个骨牌组合看作一个点,有相同数字的点中间连边,有边相连的点不可能位于一个集合,那么可以把这张图看作二分图。每个环(链)中的奇数点为一个集合,偶数点为一个集合。那么可以得到每个环(链)的点的数量为偶数
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
int f[200005],s[200005],n,ok;
int cnt[200005];
inline int find(int x){
return x==f[x]?x:f[x]=find(f[x]);
}
void slove(){
int n;
cin>>n;
ok=1;
for(int i=1;i<=n;i++)f[i]=i,s[i]=1,cnt[i]=0;
for(int i=1;i<=n;i++){
int a,b;
cin>>a>>b;
if(a>b)swap(a,b);
int fa=find(a),fb=find(b);
if(fa!=fb){
f[fb]=fa;
s[fa]+=s[fb];
}
cnt[a]++,cnt[b]++;
}
for(int i=1;i<=n;i++){
if(cnt[i]!=2){
ok=0;
break;
}
if(f[i]==i){
// cout<<" "<<i<<" : "<<s[i]<<endl;
if(s[i]%2){
ok=0;
break;
}
}
}
if(ok)cout<<"YES\n";
else cout<<"NO\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
cin>>T;
while(T--){
slove();
}
return 0;
}
F
题意
给出两个等长的a和b,每次操作可以把b中的一个元素乘2或者除以2,要求判断能否通过操作使a和b相等
思路
乘2 和 除以2 相当于位运算中的 左移1 和 右移1
先处理a:
如果a是奇数比如 3(11) 5(101)则只能通过自身得到
如果a是偶数比如 2(10) 4(100) 6(110)最小可以通过右移得到1(1) 1(1) 3(11)
对于b而言则可以左移变回a
所以只需要把a最小的情况存进map中,在对每个b进行右移操作判断是否可以变成a
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
#define int long long
#define lowbit(x) x&-x
int b[200005];
void slove(){
int n;
cin>>n;
map<int,int>mp;
for(int i=1;i<=n;i++){
int a;
cin>>a;
if(a%2==0)a/=lowbit(a);
mp[a]++;
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
int sum=0;
for(int i=1;i<=n;i++){
int a=b[i];
while(a){
if(mp[a]){
sum++;
mp[a]--;
break;
}
else a/=2;
}
if(sum<i)break;
}
if(sum==n)cout<<"YES\n";
else cout<<"NO\n";
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
cin>>T;
while(T--){
slove();
}
return 0;
}
G
题意
给出一颗树,每次询问给出若干个点,要求这若干个点是否在同一条链上
思路
先跑一边dfs预处理出来倍增lca
查询过程中先将查询的点按照深度从大到小排序
深度最大的点设置为f1
先判断是f1和当前点的lca为当前点,第一个lca不为当前点的点为f2
若不存在f2则在一条链上
否则设p1=lca(xw[i],f1),p2=lca(xw[i],f2),p=lca(f1,f2)
判断所有点是否(p1xw[i]&&p2p)||(p1p&&p2xw[i])
满足则在一条链上
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
int head[200005],nxt[400005],to[400005],cnt,pd;
int f[200005][21],dep[200005];
void add(int a,int b){
to[++cnt]=b;
nxt[cnt]=head[a];
head[a]=cnt;
}
int xw[200005];
void dfs(int x,int fa){
f[x][0]=fa;
for(int i=1;i<=20;i++){
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa)continue;
dep[y]=dep[x]+1;
dfs(y,x);
}
}
inline int read(){
int x=0;
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
int lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
for(int i=20;i>=0;i--){
if(dep[f[u][i]]<dep[v])continue;
u=f[u][i];
}
if(u==v)return v;
pd=1;
for(int i=20;i>=0;i--){
if(f[u][i]==f[v][i])continue;
u=f[u][i];
v=f[v][i];
}
return f[u][0];
}
inline bool cmp(int a,int b){
return dep[a]>dep[b];
}
void slove(){
int n=read();
for(int i=1;i<n;i++){
int a=read(),b=read();
add(a,b);add(b,a);
}
dep[1]=1;
dfs(1,0);
int q=read();
for(int i=1;i<=q;i++){
int k=read();
bool ok=1;
for(int i=1;i<=k;i++){
xw[i]=read();
}
if(k==1){
cout<<"YES\n";
continue;
}
sort(xw+1,xw+1+k,cmp);
int f1=xw[1],f2=0;
for(int i=2;i<=k;i++){
int ff=lca(f1,xw[i]);
if(xw[i]!=ff){f2=xw[i];break;}
}
if(f2==0){
cout<<"YES\n";
continue;
}
int ans=lca(f1,f2);
for(int i=1;i<=k;i++){
int ans1=lca(f1,xw[i]),ans2=lca(f2,xw[i]);
if((ans1==xw[i]&&ans2==ans)||(ans1==ans&&ans2==xw[i]))continue;
ok=0;
break;
}
if(ok)cout<<"YES\n";
else cout<<"NO\n";
}
return;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T=1;
while(T--){
slove();
}
return 0;
}