- 吴易繁 的博客
8(八)月(暑期集训)DAY03
- @ 2024-8-7 18:56:17
A. 统计单词数
题目类型:字符串
思路
对于这道题目我们可以发现,字符串是没法完全对齐的,所以字符串的前面与后面都要加上一个空格,那在这篇文章中,我们会展示两种字符串的前面与后面加上一个空格后的思路。
第一种思路
直接遍历。
第二种思路
用find函数,在这道题目中需要用到两种技巧,学会这两个技巧便可AC本题。
技巧一
(int)a.find(s);
在a字符串中查找等于s的第一个下标。
技巧二
(int)a.find(s,i);
在a字符串中从i开始,查找等于s的第一个下标。
代码
这一份代码是思路二的代码。
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("cal.in","r",stdin);
freopen("cal.out","w",stdout);
int cnt=0;
string s;
getline(cin,s);
s=" "+s+" ";
string a;
getline(cin,a);
a=" "+a+" ";
int last=1;
for(int i=1;i<s.size();i++) if(s[i]>='a'&&s[i]<='z') s[i]-=32;
for(int i=1;i<a.size();i++) if(a[i]>='a'&&a[i]<='z') a[i]-=32;
for(int i=1;i<a.size();i++){
last=(int)a.find(s,last);
if(last==-1) break;
cnt++;
last=last+1;
i=last;
}
if(cnt==0) cout<<-1;
else cout<<cnt<<" "<<(int)a.find(s);
return 0;
}
这道题目在考试的时候没有考虑包含与空格的情况,导致只得了20分,下次还是要再仔细看一下题目。
B. 瑞士轮
题目类型:排序
思路
我们先想暴力解法,但会发现超时了,因为排序费了时间,我们再看,发现赢的人是有序的,输的人也是有序的,所以可以用两个数组来分别表示赢的人与输的人,再回归到数组里。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10,M=1e5+10;
struct P{
int f,s,idx;
};
P a[N],b[M],c[M];
bool cmp(P a1,P a2){
if(a1.f==a2.f) return a1.idx<a2.idx;
else return a1.f>a2.f;
}
int main(){
freopen("ruishi.in","r",stdin);
freopen("ruishi.out","w",stdout);
int n,r,q;
cin>>n>>r>>q;
for(int i=1;i<=2*n;i++){
cin>>a[i].f;
a[i].idx=i;
}
for(int i=1;i<=2*n;i++) cin>>a[i].s;
sort(a+1,a+1+2*n,cmp);
while(r--){
int x=1,y=1;
for(int i=1;i<2*n;i+=2){
if(a[i].s>a[i+1].s){
a[i].f++;
b[x++]=a[i];
c[y++]=a[i+1];
}
else{
a[i+1].f++;
b[x++]=a[i+1];
c[y++]=a[i];
}
}
x=1,y=1;
int i=1;
while(x<=n&&y<=n){
if(cmp(b[x],c[y])) a[i++]=b[x++];
else a[i++]=c[y++];
}
while(x<=n) a[i++]=b[x++];
while(y<=n) a[i++]=c[y++];
}
cout<<a[q].idx;
return 0;
}
这道题目在写的时候写了暴力,超时了,下次要想一想AC的写法。
C. 表达式的值
题目类型:栈
思路
列举样例总结规律后,可发现这其实可总结为中缀表达式求值,但需分为结果为零和结果为一两种情况,计算法则与×和⊕相同,×为:
res.f0=(a.f0*b.f0)%10007;
res.f1=(a.f1*(b.f1+b.f0)+a.f0*b.f1)%10007;
⊕为:
res.f0=(a.f0*(b.f0+b.f1)+a.f1*b.f0)%10007;
res.f1=(a.f1*b.f1)%10007;
代码
#include<bits/stdc++.h>
using namespace std;
map<char,int> mp={{'+',1},{'*',2}};
struct P{
int f0,f1;
};
stack<P> num;
stack<char> op;
void calc(){
P b=num.top();num.pop();
P a=num.top();num.pop();
P res;
char c=op.top();op.pop();
if(c=='+'){
res.f0=(a.f0*b.f0)%10007;
res.f1=(a.f1*(b.f1+b.f0)+a.f0*b.f1)%10007;
}
else{
res.f0=(a.f0*(b.f0+b.f1)+a.f1*b.f0)%10007;
res.f1=(a.f1*b.f1)%10007;
}
num.push(res);
}
int main(){
freopen("bds.in","r",stdin);
freopen("bds.out","w",stdout);
int l;
string s;
cin>>l>>s;
num.push({1,1});
for(int i=0;i<l;i++){
if(s[i]=='(') op.push('(');
else if(s[i]==')'){
while(op.top()!='(') calc();
op.pop();
}
else{
while(op.size()!=0&&mp[s[i]]<mp[op.top()]) calc();
num.push({1,1});
op.push(s[i]);
}
}
while(op.size()) calc();
cout<<num.top().f0;
return 0;
}
这道题目完全没有思路,所以就放弃了,下一次不能轻易放弃。
D. 数列
题目类型:数学
思路
对于这道题目我们可以发现,i其实就是k进制下的i,用数组存储k的正幂次即可快速计算。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a(int a,int b){
int sum=1;
for(int i=1;i<=b;i++) sum*=a;
return sum;
}
signed main(){
freopen("num.in","r",stdin);
freopen("num.out","w",stdout);
int k,n,res=0;
cin>>k>>n;
for(int i=0;i<=20;i++) if(n>>i&1) res+=a(k,i);
cout<<res;
return 0;
}
这道题目完全没有思路,所以就放弃了,下一次不能轻易放弃。