前言
昨晚,一位五年级的巨佬来到了我们宿舍,心情好了很多。
早上
一早被叫醒,匆匆吃完早餐后,就赶紧跑到机房开始比赛了。
题目
T1:匹配
有多组数据,每组数据有以下东西:
1.一个n。
2.一串有n个字母的字符串。
然后A…M分别与Z…N配对(如A,Z),然后一个配对中的左边若在另一个配对中,另一边也一定要在这个配对中才算配对。
配对输出1,否则输出0。
T2:生日蛋糕
横竖两道把蛋糕分四份,自己取最少巧克力的那一份。
求最多能拿到多少巧克力。
T3:游戏
皇后被放置在棋盘上的某个位置,两人轮流移动,玩家1先移。每次移动玩家可以把皇后向左边移动若干步,或者向下面移动若干步,或者沿着左下方的斜线移动若干步。
谁把皇后移到左下角就获胜。
有多组数据。
T4:最大利润
你在火车站开饭店,但不允许同时在两个相连接的火车站开。任意两个火车站有且只有一条路径,每个火车站最多有50个和它相连接的火车站。
告诉你每个火车站的利润,问你可以获得的最大利润为多少。
比赛过程&&想法
一开始,看了一下第一题,用栈就可以。于是,我火速打完了代码。
(后来发现有多组数据,极其后悔)
当时预估:80分(因为当时总觉得有点怪)
接着是第二题,发现可以用暴力,不过要用前缀和。然后就花了好久对了样例。
当时预估:100分
接着是第三题,我看不出是什么,就1212的输出了。
当时预估:0分
然后就没时间做第四题了。
预估分:80+100+0+0=180
实际分:0+10+0+0=10(我好菜呀,差点爆零)
下午
听讲解加改题。
改A了第一第二题。第三第四题没时间改。
送上一二题代码。
T1
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
string c;
bool t;
int n,a[1000001],f;
int main()
{
// freopen("match.in","r",stdin);
// freopen("match.out","w",stdout);
scanf("%d",&n);
while(n)
{
t=0;
f=0;
memset(a,0,sizeof(a));
cin>>c;
for (int i=0;i<n;i++)
{
if (c[i]>='A'&&c[i]<='M')//处理左括号情况
{
f++;
a[f]=c[i]-'A'+1;
}
else if (c[i]>='N'&&c[i]<='Z')//处理右括号情况
{
if(a[f]=='Z'-c[i]+1) {a[f]=0;f--;}
else {t=1;break;}
}
}
if(f) t=1;
if (t) printf("0\n");
else printf("1\n");
n=0;
scanf("%d",&n);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
T2
#include<cstdio>
#include<iostream>
using namespace std;
int a[4501][4501],n,maxn=-1,x,y;
char c;
int main()
{
// freopen("birth.in","r",stdin);
// freopen("birth.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
cin>>c;
a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1];//求前缀和
if (c=='#') a[i][j]++;//求前缀和
}
}
for (int i=1;i<=n;i++)//枚举横切法
for (int j=1;j<=n;j++)//枚举竖切法
if (min(min(a[i][j],a[n][j]-a[i][j]),min(a[i][n]-a[i][j],a[n][n]-a[n][j]-a[i][n]+a[i][j]))>=maxn)//判断这样切能拿到的是否更多
{
maxn=min(min(a[i][j],a[n][j]-a[i][j]),min(a[i][n]-a[i][j],a[n][n]-a[n][j]-a[i][n]+a[i][j]));//如果是便记录下来
x=i;y=j;//记录切法
}
printf("%d\n%d %d",maxn,x,y);
// fclose(stdin);
// fclose(stdout);
return 0;
}
晚上
去听北京大学教授的讲座,对互联网的了解又深了很多,也明白了如何利用互联网赚钱。
极其开心。
一天总结
感觉习惯了很多。做题做的不好也不会太自卑。
不过,我还是太菜了。
后续
A掉了第三题。
其实可以用找规律来做。
代码送上。
T3
#include <cstdio>
#include <cstring>
using namespace std;
int n,x,y;
int a[100010];
int main()
{
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
scanf("%d",&n);
while (n)
{
scanf("%d%d",&x,&y);
memset(a,0,sizeof(a));
y=n-y+1;
int j=0;
bool p=0;
for(int i=1;i+j<=n;++i)
if(!a[i])
{
a[i]=1;
if((x==i&&y==i+j)||(x==i+j&&y==i))
{
printf("2\n");
p=1;
break;
}
a[i+j]=1; ++j;
}
if(!p) printf("1\n");
n=0;
scanf("%d",&n);
}
//fclose(stdin);
//fclose(stdout);
return 0;
}
n久以后终于把第四题改A了。
代码如下:
T4
#include<cstdio>
#include<iostream>
using namespace std;
int p[100001],f[100001][3],s[100001],le[100001],n,x,y,w;
struct note
{
int to,next;
}e[200001];
int dfs(int sum)
{
f[sum][1]=s[sum];
p[sum]=1;
for (int i=le[sum];i;i=e[i].next)
if (!p[e[i].to])
{
dfs(e[i].to);
f[sum][1]+=f[e[i].to][0];
f[sum][0]+=max(f[e[i].to][1],f[e[i].to][0]);
}
p[sum]=0;
}
int main()
{
// freopen("profit.in","r",stdin);
// freopen("profit.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&s[i]);
for (int i=1;i<n;i++)
{
scanf("%d %d",&x,&y);
e[++w]=(note){y,le[x]};le[x]=w;
e[++w]=(note){x,le[y]};le[y]=w;
}
dfs(1);
printf("%d",max(f[1][1],f[1][0]));
// fclose(stdin);
// fclose(stdout);
return 0;
}