Codeforces Round 962 (Div. 3)
A.legs
題解: 簡單的貪心,可以對n預處理,將n除以2,此時可將動物視為1,則動物便是1條或兩條腿,此時若是奇數才需要雞,否則全部是牛便是最優解
Show Code
#include< bits/stdc++.h >
#define ANS cout << ans << '\n'
using namespace std;
void solve()
{
int n,ans=0;
cin>>n;
n/=2;
if(n&1) ans++,n--;
n>>=1;
ans+=n;
ANS;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while(T--) solve();
return 0;
}
B.Scale
題解:簡單的模擬
Show Code
#include < bits/stdc++.h >
#define FOR(i,j,n,k) for(int i = (j);i <= (n);i +=k )
using namespace std;
solve()
{
int n,k;
cin>>n>>k;
vector< string> s(n+5);
FOR(i,1,n,1) cin>>s[i];
FOR(i,1,n,k) {
FOR(j,0,n-1,k) cout<< s[i][j];
cout<< endl;
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while(T--) solve();
return 0;
}
C.Sort
題解:簡單的字首資料結構維護處理,遍歷字串,使用int cnt[N][26]
記錄字首不同字元種類數量,由題意我們不考慮該[l,r]
區間字母的順序,只需要滿足同類字元數量相同即可,因此對於每次詢問,使用 cnt[r][j]-cnt[l-1][j]
得出該種字元在這個區間的數量並讓答案加上兩個串在該字元的數量差,最後將答案除2輸出(原始答案是重了一倍的情況)
Show Code
#include < bits/stdc++.h>
#define FOR(i,j,n,k) for(int i = (j);i <= (n);i +=k )
#define ANS cout << ans << '\n'
using namespace std;
const int N = 2e5 + 10;
int n,q;
string a,b;
int cnta[N][26],cntb[N][26];
void init()
{
a=" "+a,b=" "+b;
FOR(i,1,n,1){
FOR(j,0,25,1){
cnta[i][j]=cnta[i-1][j];
cntb[i][j]=cntb[i-1][j];
cnta[i][j]+=(a[i]-'a')==j?1:0;
cntb[i][j]+=(b[i]-'a')==j?1:0;
}
}
}
void solve()
{
cin>>n>>q;
cin>>a>>b;
init();
FOR(i,1,q,1){
int l,r,ans=0;
cin>>l>>r;
FOR(j,0,25,1){
int aa=cnta[r][j]-cnta[l-1][j];
int bb=cntb[r][j]-cntb[l-1][j];
ans+=abs(aa-bb);
}
ans/=2;
ANS;
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}
D.Fun
題解:暴力列舉,列舉a,b,時間複雜度O(nlog(n))
\[當a=1時,b<= \frac{n}{1} , 當a=2時,b<= \frac{n}{2} ,當a=i時,b<=\frac{n}{i}
\]
顯然此時出現調和數列,而調和數列的數列和約為 ln(n+1)+r 證明連結
Show Code
#include< bits/stdc++.h >
#define ANS cout << ans << '\n'
typedef long long ll;
using namespace std;
int n,k;
void solve()
{
cin>>n>>k;
ll ans=0;
for(int a=1;a<=n;a++){
for(int b=1;a*b<=n&&(a+b)< ;b++){
ans=ans+min((n-a*b)/(a+b),k-a-b);
}
}
ANS;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while(T--) solve();
return 0;
}
E.Decode
題解:大概題意:字串中每個[l,r]
區間中0,1數量相等的子串的數量和的總和字串的子串,正向思維,現找出每個子區間,再從子區間中找滿足的子串,難以進行,不妨逆向來,從滿足的子串出發,若子串滿足,其l,r可知該串對答案的貢獻值,即(l+1)*(n-r+1),即包含該串的子區間數量,於是我們正向向右推進,以i為子串的右端點,用map記錄左側已掃過的點的貢獻值,字首和的方式記錄,遇到1,temp++,否則temp--,每次走到這個右端點就找左側與之相等的點, 易錯細節即初始時mp[0]=1
Show Code
#include
using namespace std;
const int N=2e5+5;
typedef long long ll;
const int mod=1e9+7;
string s;
void solve()
{
cin>>s;
int n=s.size();
s=" "+s;
ll temp=0;
map< ll,ll> mp;
mp[0]=1;
ll ans=0;
for(int i=1;i<=s.size();i++){
if(s[i]=='1') temp++;
else temp--;
ans=ans+mp[temp]*(n-i+1)%mod;
mp[temp]+=i+1;
}
ans%=mod;
cout<< ans<< endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T;
cin>>T;
while(T--) solve();
return 0;
}