前言
由于疫情原因,今年的智慧杯没有初赛,直接复赛了。
然而我在考试的时候,由于脑子抽风,只得了320分,比预计的少了80分……😩
但是,我还是来写题解啦!😊
第一题:魔法飞毯
大水题,只要学过数组就应该能做。
方法:先从大到小排序,再取前两个的成绩输出。
代码:
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int Ar[110000];
int main()
{
freopen("carpet.in","r",stdin);
freopen("carpet.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&Ar[i]);
sort(Ar+1,Ar+1+n,cmp);
long long ans=1LL*Ar[1]*Ar[2];
printf("%lld",ans);
return 0;
}
第二题:排球比赛
大模拟,与乒乓球那题有异曲同工之妙。只不过是计分方式不同而已。
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
freopen("volleyball.in","r",stdin);
freopen("volleyball.out","w",stdout);
string str;
cin>>str;
int Acnt=0,Bcnt=0;
int Competition=1;
int ALLA=0,ALLB=0;
for(int i=0;i<str.length();i++)
{
if(str[i]=='A')
{
Acnt++;
}else if(str[i]=='B'){
Bcnt++;
}else{
break;
}
if(Competition<=4)
{
if(Acnt>=25)
{
if(Acnt-Bcnt>=2)
{
Acnt=0,Bcnt=0;
ALLA++;
Competition++;
}
}
if(Bcnt>=25)
{
if(Bcnt-Acnt>=2)
{
Acnt=0,Bcnt=0;
ALLB++;
Competition++;
}
}
}else{
if(ALLA!=ALLB) break;
if(Acnt>=15)
{
if(Acnt-Bcnt>=2)
{
Acnt=0,Bcnt=0;
ALLA++;
}
}
if(Bcnt>=15)
{
if(Bcnt-Acnt>=2)
{
Acnt=0,Bcnt=0;
ALLB++;
}
}
}
}
printf("%d:%d",ALLA,ALLB);
return 0;
}
第三题:巨石阵
就是求下标不连续的和最大的值是多少。
可用dp来做,但本人懒得一匹所以直接用模拟。
(另外,我比赛时用递归,70分……😭)
代码:
#include<bits/stdc++.h>
using namespace std;
int Ans(int Ar[],int len)
{
int sum1=0,sum2=0;
for(int i=0;i<len;i++)
{
if(i%2==0)
{
sum1=max(sum2,sum1+Ar[i]);
}else{
sum2=max(sum1,sum2+Ar[i]);
}
}
return max(sum1,sum2);
}
int Ar[1100];
int main()
{
freopen("stone.in","r",stdin);
freopen("stone.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&Ar[i]);
printf("%d",Ans(Ar,n));
return 0;
}
第四题:二师兄的纪录片
(考试的时候因为没有输出-1+数组开小活生生从100分掉到了50分😭)
先用一种很奇怪的方式求出第i行j列的点的编号:
i*n+j
然后把(i-1)*n+j
、(i+1)*n+j
、i*n+(j+1)
、i*n+(j+1)
与i*n+j
建一条长度为1的双向边。
在可以乘飞机到其他点的位置,两个点之间连一条长度为4的单向边。
与野蛮城市连接的边直接删掉。
最后跑一边已经死了的SPFA,当然,dijkstra、bellman-ford等都行,只要你保证不会TLE(当然不会)
主要问题是存边的数组要大一些,最好是 20010这种大数。
代码:
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
bool vis[250000];
int dis[250000];
int T,N;
struct node
{
int v,w;
struct node*next;
}*h[250000];
void LA(int u,int v,int w)
{
struct node *p=(struct node *)malloc(sizeof(struct node));
p->v=v;
p->w=w;
p->next=h[u];
h[u]=p;
}
void spfa(int s)
{
queue<int>Q;
memset(vis,false,sizeof(vis));
Q.push(s);
dis[s]=0;
while(!Q.empty()){
int u=Q.front();
Q.pop();
vis[u]=false;
struct node *p;
for(p=h[u];p!=NULL;p=p->next)
{
int q=p->v;
if(dis[q]>dis[u]+p->w)
{
dis[q]=dis[u]+p->w;
if(!vis[q])
{
vis[q]=true;
Q.push(q);
}
}
}
}
}
int falg[110][110];
int main()
{
freopen("record.in","r",stdin);
freopen("record.out","w",stdout);
int n,p,q;
scanf("%d%d%d",&n,&p,&q);
memset(dis,inf,sizeof(dis));
memset(h,0,sizeof(h));
for(int i=0;i<p;i++)
{
int x,y;
scanf("%d%d",&x,&y);
falg[x][y]=1;
}
for(int i=0;i<q;i++)
{
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
LA(x1*n+y1,x2*n+y2,4);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int Point=i*n+j;
if(i-1>=1 && falg[i-1][j]!=1)
{
LA(Point,(i-1)*n+j,1);
}
if(i+1<=n && falg[i+1][j]!=1)
{
LA(Point,(i+1)*n+j,1);
}
if(j-1>=1 && falg[i][j-1]!=1)
{
LA(Point,i*n+(j-1),1);
}
if(j+1<=n && falg[i][j+1]!=1)
{
LA(Point,i*n+(j+1),1);
}
}
}
spfa(1*n+1);
if(dis[n*n+n]==inf)
{
puts("-1");
return 0;
}
printf("%d\n",dis[n*n+n]+1);
return 0;
}
最后
最后,我还是要提醒大家:
不开long long见祖宗,
数组开小全RE。
RE与TLE·组歌
血的教训