给您带来优质的代码体验,给您带来欢喜^_^
做一套有意思的题、领悟巧妙的算法难道不比玩游戏、看小说强上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;
}
认真并快乐地过好生命中的每一分钟。