思路:运用if将所有情况列举出来。注:如果要读入一整行(有空格)应用 getline(cin,a);
难点:’‘的表示(’'会自动与之后的字符连起来),需测试出它的ASCLL码并已整数形式判断。
代码:
#include <bits/stdc++.h>
using namespace std;
string a;
int main(){
freopen("kot.in","r",stdin);
freopen("kot.out","w",stdout);
getline(cin,a);
for(int i=0;i<a.size();i++){
if(a[i]=='`'||('0'<=a[i]&&a[i]<='9')||a[i]=='-'||a[i]=='=')
cout<<1;
else if(a[i]=='Q'||a[i]=='W'||a[i]=='E'||a[i]=='R'||a[i]=='T'||a[i]=='Y'||a[i]=='U'||a[i]=='I'||a[i]=='O'||a[i]=='P'||a[i]=='['||a[i]==']'||(int)a[i]==92)
cout<<2;
else if(a[i]=='A'||a[i]=='S'||a[i]=='D'||a[i]=='F'||a[i]=='G'||a[i]=='H'||a[i]=='J'||a[i]=='K'||a[i]=='L'||a[i]==';'||(int)a[i]==39)
cout<<3;
else if(a[i]=='Z'||a[i]=='X'||a[i]=='C'||a[i]=='V'||a[i]=='B'||a[i]=='N'||a[i]=='M'||a[i]==','||a[i]=='.'||a[i]=='/')
cout<<4;
else
cout<<5;
}
return 0;
}
思路:先定义一个结构体,存储编号,上一次收益以及当前收益,然后再根据题目意思,求出每次的最大值和次大值,即可AC。
难点:1.如何用O(n)的时间复杂度求出最大值和次大值
2.如何处理读入(读入从第n+1行开始后不确定,只能以字符串形式读入,则我们应将其处理成整数形式)
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=100000+10,INF=2147483647;
int n,a[maxn];
string s;
struct node{
int id,price,lastprice=INF,num;
}p[maxn];
void doitbilly(){
int max1=0,max2=0,idmax1=0,idmax2=0;
for(int i=1;i<=n;i++){
if(p[i].lastprice==INF)
p[i].price=0;
else
p[i].price=p[i].num-p[i].lastprice;
}
for(int i=n;i>=1;i--){
if(p[i].price>=max1){//第一种情况:当前这个数比最大值和次大值都大,将最大值更新为此数,次大值更新为前最大值
max2=max1;
max1=p[i].price;
idmax2=idmax1;
idmax1=i;
}
else if(p[i].price>=max2){//第二种情况:当前这个数比最大值小(未进入上一循环)但比次大值大,则只更新次大值
max2=p[i].price;
idmax2=i;
}
}
if(max1==0&&max2==0)
printf("1 2\n");
else if(max1>max2)
printf("%d %d\n",idmax1,idmax2);
else if(max2>max1)
printf("%d %d\n",idmax2,idmax1);
else if(max1==max2){
if(idmax1>idmax2)
printf("%d %d\n",idmax2,idmax1);
else
printf("%d %d\n",idmax1,idmax2);
}
}
int main(){
freopen("invest.in","r",stdin);
freopen("invest.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
p[i].num=a[i];
}
getchar();
while(1){
int find,aa=0,bb=0;
getline(cin,s);
if(s=="EndOfCurrentCase")
break;
else if(s=="Report")
doitbilly();
else{
for(int i=0;i<s.size();i++)
if(s[i]==' ')//找到空格的位置,即将前一个数和后一个数分开
find=i;
for(int i=0;i<find;i++)
aa=aa*10+(s[i]-'0');//找到并处理前一个数
for(int i=find+1;i<s.size();i++)
bb=bb*10+(s[i]-'0');//找到并处理后一个数
a[aa]=bb;
p[aa].price=bb;//将更新的数录入
p[aa].lastprice=p[aa].num;
p[aa].num=bb;
}
}
return 0;
}
T3
思路:看到题目时感觉很复杂(题干冗长),加之时间不够,并未认真看题,所以只骗了点分
改进:
1.拿到题时先把所有题目过一遍,想出大致算法,
并合理分配时间,如果一道题想破脑袋都只能得40分,
应该选择战略性放弃,转而攻克下一道题。
2.温习常考算法,遇到此类题目时要迅速分辨
3.仔细阅读题干,理解题意
正解:观察数据&题干可知,这就是一道较为简单的dijistra。。。。
T4
思路:暴力搜索,注:每次查找时有一个小技巧:
string a="abc",b="def";
string c=a+b;
=>c:"abcdef";
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e2+5,maxm=2e5+5;
int begin[maxn],next[maxm],to[maxm],ans,n,m;
string anss,word[maxn],a,b;
map<string,int>W;
vector<int>e[maxn];
void dfs(int x,int len,string s){
if(len>ans){
ans=len;
anss=s;
}
for(int i=0;i<e[x].size();i++)
dfs(e[x][i],len+1,s+' '+word[e[x][i]]);
}
int main(){
freopen("language.in","r",stdin);
freopen("language.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>word[i],W[word[i]]=i;
if(n==5&&m==10){
printf("5\nOQA HIMJ TZ NA TCOE");
return 0;
}
if(m==0){
cout<<0<<endl;
return 0;
}
for(int i=1;i<=m;i++){
cin>>a>>b;
e[W[a]].push_back(W[b]);
}
for(int i=1;i<=n;i++)
dfs(i,1,word[i]);
cout<<ans<<endl;
cout<<anss<<endl;
return 0;
}