給您帶來優質的代碼體驗,給您帶來歡喜^_^
做一套有意思的題、領悟巧妙的算法難道不比玩遊戲、看小說強上100倍?
A題
簽到
B題
神奇!神奇!substr和優先隊列真是神奇!AC的快樂纔是真正的快了吧!
題目大意:
給你一個字符串S,問你長度爲k且出現次數超過兩次的子串有多少種,按字典序輸出。
解題思路:先遍歷一遍,並且用map計數,之後再遍歷一遍,如果次數大於2,存入數組,並且次數置零。sort排序輸出。
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
//const int maxn=1;
//const int mod=1e9+7;
map<string,int> mp;
priority_queue<string,vector<string>,greater<string> > p;
int main()
{
// freopen("input.txt","r",stdin);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s;
int k;
cin>>s>>k;
for(int i=0;i<s.length();i++)
{
string s2=s.substr(i,k);
mp[s2]++;
}
for(int i=0;i<s.length();i++)
{
string s3=s.substr(i,k);
if(mp[s3]>2)
{
mp[s3]=0;
p.push(s3);
}
}
cout<<p.size()<<endl;
while(!p.empty())
{
string s4=p.top();
p.pop();
cout<<s4<<endl;
}
return 0;
}
1、做的過程中電腦出現問題,懷疑string不能有數組,後來發現原來行,覺着應該所有類型都能建數組。
2、嘖嘖,寫這道題的時候忘記優先隊列的頭文件了,結果沒用優先隊列,其實。。。用萬能頭文件就行啊,虧我練了那麼久的萬能頭文件。
D題
解題思路:
易知,一個點狀態的改變取決於這個點的變化、所在行的變化、所在列的變化。
取一個點M爲(x,y),則這個點所在的行和列都會發生變化。當Q個點取完之後,設點M出現的次數爲a,點M所在行x出現的次數爲b,點M所在列y出現的次數爲c。則這個點的變化次數爲(b-a)+(c-a)+a=b+c-a.
//#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
const int maxn=1e5+10;
map<int,int> mpx,mpy;
map<pair<int,int>,int> mpdot;//map中使用pair
int main()
{
// freopen("input.txt","r",stdin);
int row,col,n;
cin>>row>>col>>n;
pair<int,int> Dot;//雙int的pair類型Dot變量
for(int i=0;i<n;i++)
{
int x,y;
cin>>x>>y;
mpx[x]++,mpy[y]++;
Dot={x,y};
mpdot[Dot]++;
}
int ans=0;
for(int i=1;i<=row;i++)
{
for(int j=1;j<=col;j++)
{
Dot={i,j};
int a=mpdot[Dot],b=mpx[i],c=mpy[j];
if((b+c-a)%2==1) ans++;
}
}
cout<<ans;
return 0;
}
E題
有規律,直接長度/2就行。
F題
題目大意:
你如果之前沒看懂的話,估計是沒有注意product這個詞。這個詞有“[數]乘積”的意思。
下次再一直看不懂題意,就要一個單詞一個單詞認真扣了。
解題思路:
模擬就行。
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn=1e9+7;
int main()
{
int n;
cin>>n;
ll ans=0;
ll sum=1;
for(int i=0;i<n;i++)
{
string s,s1;
int a,b;
cin>>s;
if(s=="begin") continue;
else if(s=="for")
{
cin>>s1;
cin>>a>>b;
sum*=(b-a+1);
sum=sum%maxn;
}
else if(s=="end")
{
ans=(ans+sum)%maxn;
sum=1;
}
}
cout<<ans;
return 0;
}
值得注意的是,我以爲數很大需要用到大數取餘呢。之前遇到說數很大要取餘就很怕,結果這道題(可能很多題都這樣),在分步進行的過程中分別取餘就ok了,也是很歡喜了。
G題
看懂題意簽到吧。
J題
題目大意:
給你一個數n,這個數化成二進制序列S,這個二進制序列複製n次成爲序列T。問T中滿足Ti=′1′,Tj=′1′,Tk=′0′,且1≤i<j<k≤|T|的
(i,j,k) 有多少組。
解題思路:
要求(i,j,k) 有多少組,可以從每個0前面有多少個1開始。對n除以2取二進制碼,遇到0的時候,記錄0的個數,同時使用map容器記錄0前面1的個數、記錄1的總個數sum。根據題意當一個0前面1的個數爲a時,則對這個0來說,滿足條件的組數爲a*(a-1)。若第一組某個0滿足條件的組數爲a*(a-1),則第二組相應位置上的0滿足條件的組數爲(a+sum)*[(a+sum)-1],第三組相應位置上的0滿足條件的組數爲(a+2*sum)*[(a+2*sum)-1],後面的依次類推。
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
//const int maxn=1;
const int mod=1e9+7;
map<ll,ll> mp;//每個0前面1的個數
int main()
{
// freopen("input.txt","r",stdin);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll t;
cin>>t;
while(t--)
{
mp.clear();
int n;
cin>>n;
ll sum0=0,sum1=0;
ll m=n;
while(m)
{
if(m%2==0)
{
sum0++;//0的數目、下標從1開始
}
else
{
sum1++;
for(ll i=1;i<=sum0;i++) mp[i]++;
}
m/=2;
}
ll ans=0;
for(ll i=1;i<=n;i++)
{
for(ll j=1;j<=sum0;j++)
{
ans=(ans+(mp[j]+(i-1)*sum1)*((mp[j]+(i-1)*sum1)-1)/2)%mod;
}
}
cout<<ans%mod<<endl;
}
return 0;
}
哈哈,沒想到我也有寫出來這道題的時候。之前以爲可難類,原來去嘗試了,就變簡單了。開始的時候n的值一直變化,變化到0了,給忘記了,結果錯了。然後,map忘清零了,又錯了。最後卡ll了,又錯了。看來還是做題少,意識不夠。多組數據輸入,記得每次初始化,用到ll的地方一定要全部改成ll。把致錯因素一開始就掌握到極致。總之,做出來這道題還是很高興的,自信!
L題
(沒時間了,不想寫了,直接cv咯)
要使中的貢獻最小,首先把除了第一項以外的值全部置爲11,僅考慮第一項的值即可,假設表達式的值爲00,計算出兩個式子第一項值爲a,ba,b,那麼我們就進行如下操作:若其中一項不爲正數,則兩個數均加上一個值使得兩個數均爲正數。這樣可以使得兩個式子值相同且貢獻儘可能的小。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2000000+10;
char s[maxn],t[maxn];
void solve(){
int n;
scanf("%d",&n);
scanf("%s %s",s,t);
int a=0,b=0;
for(int i=0;i<n;i++){
if(s[i]=='-') a++;
else a--;
if(t[i]=='-') b++;
else b--;
}
int prea,preb;
prea=a+max(1-min(a,b),0);
preb=b+max(1-min(a,b),0);
printf("%d %d\n",0,prea+preb+n*2);
printf("%d",prea);
for(int i=1;i<=n;i++) printf(" %d",1);
printf("\n");
printf("%d",preb);
for(int i=1;i<=n;i++) printf(" %d",1);
printf("\n");
}
int main()
{
solve();
return 0;
}
認真並快樂地過好生命中的每一分鐘。