K
写一下二进制你会发现可以按照首位二进制分类
#include <bits/stdc++.h>
using namespace std;
int a[102000];
int mark[100];
int main(){
int T;
ios::sync_with_stdio(0);
cin>>T;
while(T--){
int n;cin>>n;
memset(mark,0,sizeof(mark));
int Max=0;
for(int i=1;i<=n;i++){
cin>>a[i];
int cnt=0;
while(a[i]){
a[i]/=2;
++cnt;
}
mark[cnt]++;
Max=max(Max,mark[cnt]);
}
printf("%d\n",Max);
}
return 0;
}
A
我们可以枚举分段数量 然后用最小的nonperfect去分割看总和是否小于等于n小于就可以加进答案
如
PPP N PPP N PPP
用两个N即可分成三段
#include <bits/stdc++.h>
using namespace std;
int a[102000];
int mark[100];
int main(){
int T;
ios::sync_with_stdio(0);
cin>>T;
while(T--){
int n,m;
cin>>n>>m;
int ans1=m;
int ans2=0;
for(int i=1;i<=m;i++){
int t=m%i==0?m/i:m/i+1;
if(t-1+m<=n){
ans2=i;
break;
}
}
cout<<ans1<<" "<<ans2<<endl;
}
return 0;
}
C题
模拟
二维数组可以保存状态 显然每个状态会对应到下一个状态 直接循环or 搜索即可 dfs可能爆栈??
#include <bits/stdc++.h>
using namespace std;
struct node{
string instruct;
int data;
int k;
}p[10200];
int n;
bool ok;
bool vis[10005][257];
int main(){
int T;
ios::sync_with_stdio(0);
cin>>T;
while(T--){
memset(vis,0,sizeof(vis));
cin>>n;
ok=true;
for(int i=1;i<=n;++i){
string temp;
cin>>temp;
p[i].instruct=temp;
cin>>p[i].data;
if(temp[1]!='d'){
cin>>p[i].k;
}
}
int step=1;
int now=0;
while(1){
if(step==n+1) break;
if(!ok) break;
if(vis[step][now]){
ok=false;
break;
}
else vis[step][now]=true;
if(p[step].instruct[1]=='d'){
now=(now+p[step].data)%256;
step++;
}
else if(p[step].instruct[1]=='e'){
if(now==p[step].data){
step=p[step].k;
}
else{
step++;
}
}
else if(p[step].instruct[1]=='n'){
if(now!=p[step].data){
step=p[step].k;
}
else{
step++;
}
}
else if(p[step].instruct[1]=='l'){
if(now<p[step].data){
step=p[step].k;
}
else{
step++;
}
}
else if(p[step].instruct[1]=='g'){
if(now>p[step].data){
step=p[step].k;
}
else{
step++;
}
}
}
if(ok){
puts("Yes");
}
else puts("No");
}
return 0;
}
H
写的有点复杂
每次根据上一次状态计算总和
比如
1011010
1235678
235678
13456
1234
234
12
2
观察一下相邻两列的关系推公式
00100
24568
2346
124
24
2
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll a[102000];
ll f[102000];
int main(){
int T;
ios::sync_with_stdio(0);
cin>>T;
while(T--){
string s;
cin>>s;
int len=s.size();
s='#'+s;
if(s[1]=='1') a[1]=1;
else a[1]=2;
for(int i=2;i<=len;++i){
if(s[i]==s[i-1]) a[i]=a[i-1]+2;
else a[i]=a[i-1]+1;
}
ll sum=0;
for(int i=1;i<=len;++i){
sum+=a[i];
}
ll ans=sum;
ll last=sum;
for(int i=2;i<=len;++i){
ll temp=0;
if(s[i]=='0'){
if(s[i-1]=='0'){
temp=last-2*(len-i+1)-(s[i-1]=='0'?2:1);
}
else temp=last-1;
}
else temp=last-2*(len-i+1)-(s[i-1]=='0'?2:1);
ans+=temp;
last=temp;
}
cout<<ans<<endl;
}
return 0;
}