A题链接
题意:
让 n 的最高位减去 1
代码如下
#include<bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define pb push_back
#define x first
#define y second
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define LL long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f;
#define LNF 0x3f3f3f3f3f3f3f3f;
#define PI acos(-1)
using namespace std;
int qmi(int a,int k)
{
int res=1;
while(k)
{
if(k&1) res=(LL)res*a;
k>>=1;
a=(LL)a*a;
}
return res;
}
void solve()
{
int n;
cin>>n;
int idx=0;
int k=n;
while(k)
{
idx++;
k/=10;
}
cout<<n-qmi(10,idx-1)<<endl;
}
B题链接
题意:
一个人,每天能记三个字母,问写出这个字符串需要几天
解题思路:
用 vector 存天记的三个字母,如果 vector 是空的,天数 +1,然后把当前字母放进去,每次读一个字母,然后去和 vector 里面的字母匹配,如果没有就放进去,如果vector存的字母超过三个,天数+1,然后清空 vector。
#include<bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define pb push_back
#define x first
#define y second
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define LL long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f;
#define LNF 0x3f3f3f3f3f3f3f3f;
#define PI acos(-1)
using namespace std;
void solve()
{
string s;
cin>>s;
vector<char> v;
int ans=1;
v.pb(s[0]);
rep(i,1,s.size()-1)
{
bool bo=0;
for(char j:v)
if(j==s[i])
{
bo=1;
break;
}
if(!bo)
{
if(v.size()<3)
v.pb(s[i]);
else
{
v.clear();
v.pb(s[i]);
ans++;
}
}
}
cout<<ans<<endl;
}
题意:
n 个数字,询问 a 和 b,如果( a 或者 b 不存在)或者( a 的后面找不到 b ),就输出 NO,如果满足,就输出 YES
解题思路:
用 map 存某个站牌第一次出现的位置和最后一次出现的位置,用 map 来判断 a 和 b 站牌是否存在。
每次查询的时候,先判断 a 和 b 是否存在,判断 a 的左端点对否在 b 的右端点之前,如果 a 在 b 之前,就输出 YES,否则就输出 NO
代码如下:
#include<bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define pb push_back
#define x first
#define y second
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define LL long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f;
#define LNF 0x3f3f3f3f3f3f3f3f;
#define PI acos(-1)
using namespace std;
void solve()
{
int n,k;
cin>>n>>k;
map<int ,PII> mp;
rep(i,1,n)
{
int k;
cin>>k;
if(mp[k].x==0)
mp[k].x=i;
mp[k].y=max(mp[k].y,i);
}
while(k--)
{
int l,r;
cin>>l>>r;
if(mp[l].y==0||mp[r].y==0)
{
cout<<"NO"<<endl;
continue;
}
if(mp[l].x>mp[r].y)
cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
题意:
给一个字符串 s 和一个数字 n ,请问删除最少的字符,让剩余字符串的值的和 ≤ n,字符串值的和为 s [ i ] - ‘a’ + 1。输出删除后的字符串,并让每个字符保持原有的顺序。
解题思路:
先求出原字符串的值的和,如果 ≤ n,直接输出 s 即可。否则从值最大的字符开始删除,一直删到 ≤ n。
我用 map 存的每个字符的个数,输出的时候每个字符输出指定个数即可。
代码如下:
#include<bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define pb push_back
#define x first
#define y second
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define LL long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f;
#define LNF 0x3f3f3f3f3f3f3f3f;
#define PI acos(-1)
using namespace std;
void solve()
{
int a;
string s;
cin>>s>>a;
LL ans=0;
map<char,int> mp;
rep(i,0,s.size()-1)
{
ans+=(s[i]-'a')+1;
mp[s[i]]++;
}
// cout<<ans<<endl;
for(char i='z';i>='a';i--)
{
if(!mp[i])
continue;
while(ans>a&&mp[i])
{
ans-=(i-'a')+1;
mp[i]--;
}
// cout<<ans<<endl;
}
string st="";
rep(i,0,s.size()-1)
{
if(mp[s[i]])
{
st+=s[i];
mp[s[i]]--;
}
}
cout<<st<<endl;
}
题意:
给 n 组(x,y),他们分成两组,让这两组中,所有小组的 x 和 y 都是单独的,换句话说,每组中,x 和 y 恰好能组成 1~n 的排列。
如果能。就输出 YES,否则输出 NO。
解题思路:
用并查集,随便分组就行(遇到 x 和 y ,就把他俩放到一个连通块当中就行),如果 x==y 就输出NO就行,同样的,如果一个数大于 2 了,也要输出 NO(但是要读完所有 x,y )
然后统计一个连通块中的个数,如果是奇数就输出 NO 就行
否则就输出 YES 即可
代码如下:
#include<bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define pb push_back
#define x first
#define y second
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define LL long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f;
#define LNF 0x3f3f3f3f3f3f3f3f;
#define PI acos(-1)
using namespace std;
const int N=2e5+10;
int a[N],num[N];
int p[N];
int find(int x)
{
if (p[x] != x)p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n;
cin>>n;
vector<int> ans;
rep(i,1,n)
a[i]=0,p[i]=i,num[i]=1;
bool bo=0;
rep(i,1,n)
{
int x,y;
cin>>x>>y;
a[x]++,a[y]++;
if(x==y) bo=1;
int fx=find(x),fy=find(y);
if(fx!=fy)
{
p[fx]=fy;
num[fy]+=num[fx];
}
}
rep(i,1,n)
{
if(bo||num[find(i)]%2==1||a[i]>2)
{
cout<<"NO"<<endl;
return;
}
}
cout<<"YES"<<endl;
memset(a,0,sizeof a);
}
题意:
能否吧数组b变成数组a,每次可以 ×2 或者 ÷2
解题思路:
把所有的 a 和 b 变成奇数就行。然后用 map 存 a 的值,排序 b 之后,用 b 去匹配 a,如果匹配不到,就让当前的 b÷2,直到 b==0 的时候,输出 NO,如果匹配到了,就让mp[b]–。
代码如下:
#include<bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define dec(a,b,c) for(int a=b;a>=c;a--)
#define pb push_back
#define x first
#define y second
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define LL long long
#define PII pair<int,int>
#define INF 0x3f3f3f3f;
#define LNF 0x3f3f3f3f3f3f3f3f;
#define PI acos(-1)
using namespace std;
const int N=2e5+10;
int a[N],b[N];
int check(int k)
{
while(k%2==0)
{
k/=2;;
}
return k;
}
void solve()
{
int n;
cin>>n;
map<int,int> mp;
rep(i,1,n)
cin>>a[i],a[i]=check(a[i]),mp[a[i]]++;
rep(i,1,n)
cin>>b[i],b[i]=check(b[i]);
sort(b+1,b+1+n);
rep(i,1,n)
{
while(b[i]&&!mp[b[i]])
{
b[i]/=2;
}
if(b[i]==0)
{
cout<<"NO"<<endl;
return;
}
else mp[b[i]]--;
}
cout<<"YES"<<endl;
}