A. Legs
题意:有n条腿,鸡有两条,牛有四条,最少有几只动物
分析:判断牛最多几头,再判断是否有鸡
代码:
#include<bits/stdc++.h> using namespace std; void sol(){ int n;cin>>n; if(n%4==0) cout<<n/4<<endl; else cout<<n/4+1<<endl; } int main(){ int t;cin>>t; while(t--)sol(); }
B. Scale
题意:有n×n的网格,每k×k的网格里的格子都是一样的,将它变成一个网格
分析:枚举每个子网格,并更改即可
代码:
#include<bits/stdc++.h> using namespace std; void sol(){ int n,k;cin>>n>>k; char a[n+10][n+10]; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>a[i][j]; } } int c=n/k; for(int i=1;i<=n;i+=k){ for(int j=1;j<=n;j+=k){ if(a[i][j]=='0')cout<<"0"; else cout<<"1"; } cout<<endl; } } int main(){ int t;cin>>t; while(t--)sol(); }
C. Sort
题意:给定两个字符串a,b,区间l,r内a和b都从小到大排序,问需要几次操作(任选一个元素变成另一个元素)才能使区间lr内a和b完全相同
分析:元素一共只有26种,可以用二维数组读入。输出区间内的每个元素差值相加即可。
代码:
#include<bits/stdc++.h> using namespace std; void sol(){ vector<vector<int>>cc; int n,q;cin>>n>>q;cc.resize(n+1,vector<int>(26,0)); string a,b;cin>>a>>b; for(int i=1;i<=n;i++){ cc[i]=cc[i-1]; int c=a[i-1]-'a'; int d=b[i-1]-'a'; cc[i][c]++; cc[i][d]--; } while(q--){ int l,r;cin>>l>>r;int sum=0; for(int i=0;i<26;i++){ sum+=max(cc[r][i]-cc[l-1][i],0); } cout<<sum<<endl; } } int main(){ int t;cin>>t; while(t--)sol(); return 0; }
D. Fun
题意:找出满足ab+ac+bc<=n&&a+b+c<=x的a,b,c的个数
分析:遍历a,遍历符合条件的b,找出两个式子c的最大值的最小值相加。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; void sol(){ int n,x;cin>>n>>x;ll ans=0; for(int a=1;a<=n;a++){ for(int b=1;a+b<=x&&(ll)a*b<=n;b++){ ans+=min(x-a-b,(n-a*b)/(a+b)); } } cout<<ans<<endl; } int main(){ int t;cin>>t; while(t--)sol(); return 0; }
E. Decode
题意:给定一个二进制字符串s,对于l,r的每对整数x,y,计算下x,y的对数个数,l,r中的0的数量等于x,y中的1的数量
分析:如果si=1,ai=1.如果si=0,ai=-1.用p表示a的前缀和数组。如果py-p(x-1)=0,就说明0和1的个数一样。lr的个数就是(n-i+1)*fx,fx为l可以取的值
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; void sol(){ string s;cin>>s; int n=s.size(); s='#'+s; vector<ll>a(n+1); for(int i=1;i<=n;i++){ if(s[i]=='1')a[i]=1; else a[i]=-1; } map<ll,ll>mp; mp[0]=1; int ans=0;ll sum=0; for(int i=1;i<=n;i++){ sum+=a[i]; ans+=(n-i+1)*mp[sum]%mod; ans%=mod; mp[sum]+=i+1; } cout<<ans<<endl; } int main(){ int t;cin>>t; while(t--)sol(); return 0; }
F. Bomb
题意:给两个数组a和b,最初分数是0.每次操作可以任意加入一个ai并将ai变成max(0,ai-bi)。求最大分数。
分析:用二分找出一个数,这个数以上的数都要取。然后用等差数列求和将这些符合条件的加入,然后再减去多余操作的。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; ll a[N],b[N];int n; ll f(ll x){ ll sum=0; for(int i=1;i<=n;i++){ if(a[i]<x)continue; sum+=(a[i]-x)/b[i]+1; } return sum; } void sol(){ cin>>n;ll k;cin>>k; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++)cin>>b[i]; ll l=0,r=1e18; while(l+1<r){//找到一个数,从这个数以上的都要加入 ll mid=(l+r)>>1; if(f(mid)<k)r=mid; else l=mid; } if(f(r)==k)l=r; r=l; ll ans=0,d=0; for(int i=1;i<=n;i++){ if(a[i]<r)continue; ll v=(a[i]-r)/b[i]+1; ans+=a[i]*v-v*(v-1)*b[i]/2; d+=v; } cout<<ans-(d-k)*r<<endl; return; } int main(){ int t;cin>>t; while(t--)sol(); return 0; }