B.签到题
有话说:我,我被题目给欺骗了,当大多数人在写A题的时候,我奔向了B。
题目:
IG牛逼!!!
众所周知,IG是英雄联盟S8世界总决赛冠军,夺冠之夜,数亿人为之欢呼!
赛后某百分百胜率退役ADC选手的某表情包意外走红,某苟会长看到此表情包也想模仿。
于是有n个友爱的萌新决定每人都送会长一根长为ai面包。(数据保证没有面包的长度相等)
会长无聊时把面包摆成一排,他惊人地发现他喜欢这样一类区间,区间[i, j]满足条件:
区间里的面包没有比左端点i号面包短的,同时也没有比右端点j号面包长的。
Gey会长在思考这样一个问题:
所有满足条件的区间中j-i的最大值是多少?
Inputt组样例。
每组样例第一行输入整数n。
第二行输入n个正整数。(t<=30, n<=1000, ai<=1000000)
Output
输出满足条件的区间中j-i的最大值。
Sample Input 1
2
4
5 4 3 6
4
6 5 4 3
Sample Output 11
0
思路:我读题一共读了4,5次…因为没看懂题目想了好一会。其实总结一下:
给你一个大区间A,找到这样一个小区间【i,j】,此小区间满足【区间内的所有数字都比A[i]大,比A[j]小】,问【j-i】的最大值,即区间长度。
没有算法,就是硬肛 写。
此代码为比赛时的代码,含义有点混乱。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
using namespace std;
struct node
{
int a,b;
};
int main()
{
int T,n,sum,i,j,mi,ma,flag,t,tt,k;
struct node x[1010];
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d",&x[i].a);//a是面包长度
x[i].b=i;/*b是号码,虽然并没有什么用*/
} /*这是历史代码遗留问题*/
sum=0;//所求每次初始化
for(i=1; i<=n; i++)
{
mi=x[i].b;//表示小区间的i
k=x[i].a;//长度
for(j=i+1; j<=n; j++)//往后推
{
if(x[i].a>x[j].a)//一旦有面包长度大于k
{
break;/*退出循环*/
}
if(k<x[j].a)/*往后推的意思,很容易理解的*/
{
k=x[j].a;
ma=x[j].b;//表示小区间的j
t=ma-mi;//t表示此时的j-i的值
if(t>sum)/*sum永远为最大值*/
{
sum=t;
}
}
}
}
printf("%d\n",sum);
}
}
}
A.送气球.jpg
ACM-ICPC程序设计大赛是大学级别最高的脑力竞赛,素来被冠以"程序设计的奥林匹克"的尊称。大赛至今已有近40年的历史,是世界范围内历史最悠久、规模最大的程序设计竞赛。比赛形式是:从各大洲区域预赛出线的参赛队伍,于指定的时间、地点参加世界级的决赛,由1个教练、3个成员组成的小组应用一台计算机解决7到13个生活中的实际问题。在正式赛场中,一个队伍每解决一个新的问题就会有一个相应的气球作为奖励送到这个队伍所在的位置。
Dillonh作为这次ACM-ICPC的志愿者,当然是时刻关注着场上的过题情况的,每当有一个队伍通过新的问题的时候,他就会马上送上气球。但由于参赛队伍实在是太多了,他也不清楚每个队伍得到了多少个气球。在比赛结束之后,他拿到了一份这场比赛的题目提交情况,他想知道现场参加比赛的队伍每个队伍能获得多少个气球,聪明的你能帮帮他吗?
Input
第一行包含一个整数T(T<=10),表示总共有T组测试样例;
第二行输入一个整数n,m;
n表示有多少个队伍参加这次的比赛(1<=n <= 50);
m表示有多少条提交记录(1<=m<=1000);
接下来输入m行,每行输入格式如下:
team_id problem_id submit_status
team_id 代表着队伍的编号(1 <= team_id <= n);
problem_id代表着题目编号(为A~M的大写字母);
submit_status代表着这个题目提交的结果(可是"AC",“PE”,“TLE”,“MLE”,“WA”,“RE”,"CE"其中的一种)。Output
对于每组样例
第一行输出一行“Case #x:”,x表示当前为第几组样例(详细见样例);
第二行输出n个数(每两个数之间用空格隔开)代表着第 i 个队可以获得的气球数量。(注意不要在每一行的末尾输出多余的空格)。
Sample Input 1
1
5 10
1 A WA
1 A AC
2 A AC
3 C TLE
2 C TLE
1 C AC
3 A AC
4 A AC
1 A AC
5 A WA
Sample Output 1
Case #1:
2 1 1 1 0
思路:我由于傻了,在用了get()后还试图用strcmp去比较导致我看了半天…后来发现对自己无语了,真实签到题,傻瓜式写法。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
struct node
{
int flag[24];
} x[1010];
int main()
{
int n,T,m,i,j,k,a,num[1010];
char b;
char c[10];
while(scanf("%d",&T)!=EOF)
{
for(k=1; k<=T; k++)
{
scanf("%d %d",&n,&m);
for(i=1; i<=n; i++)
{
for(j=1; j<23; j++)
{
x[i].flag[j]=0;
}
}
memset(num,0,sizeof(num));
for(i=1; i<=m; i++)
{
scanf("%d%*c%c%*c%s",&a,&b,c);
if(strcmp(c,"AC")==0)
{
if(b=='A'&&x[a].flag[1]==0)
{
x[a].flag[1]=1;
num[a]++;
}
else if(b=='B'&&x[a].flag[2]==0)
{
x[a].flag[2]=1;
num[a]++;
}
else if(b=='C'&&x[a].flag[3]==0)
{
x[a].flag[3]=1;
num[a]++;
}
else if(b=='D'&&x[a].flag[4]==0)
{
x[a].flag[4]=1;
num[a]++;
}
else if(b=='E'&&x[a].flag[5]==0)
{
x[a].flag[5]=1;
num[a]++;
}
else if(b=='F'&&x[a].flag[6]==0)
{
x[a].flag[6]=1;
num[a]++;
}
else if(b=='G'&&x[a].flag[7]==0)
{
x[a].flag[7]=1;
num[a]++;
}
else if(b=='H'&&x[a].flag[8]==0)
{
x[a].flag[8]=1;
num[a]++;
}
else if(b=='I'&&x[a].flag[9]==0)
{
x[a].flag[9]=1;
num[a]++;
}
else if(b=='J'&&x[a].flag[10]==0)
{
x[a].flag[10]=1;
num[a]++;
}
else if(b=='K'&&x[a].flag[11]==0)
{
x[a].flag[11]=1;
num[a]++;
}
else if(b=='L'&&x[a].flag[12]==0)
{
x[a].flag[12]=1;
num[a]++;
}
else if(b=='M'&&x[a].flag[13]==0)
{
x[a].flag[13]=1;
num[a]++;
}
}
}
printf("Case #%d:\n",k);
for(i=1; i<n; i++)
{
printf("%d ",num[i]);
}
printf("%d\n",num[n]);
}
}
}
3.题目:总结就是所有小于等于N的与6无关的正整数的平方和。
和那道与7无关的那题是一样的。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
int main()
{
int t,flag,n;
long long sum,tt,i,j;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
sum=0;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
flag=0;
if(i%6==0)
{
flag=1;
}
else
{
tt=i;
while(tt>0)
{
if(tt%10==6)
{
flag=1;
break;
}
tt/=10;
}
}
if(flag==0)
{
sum+=i*i;
}
}
printf("%lld\n",sum);
}
}
}
4.M.被打脸的潇洒哥
链接:https://ac.nowcoder.com/acm/contest/318/M
“画个圈圈诅咒你!”
在一次青青草原ACM个人赛中,潇洒哥被喜洋洋以30s罚时压制,委屈的当了个第二。潇洒哥蹲在角落说出了他的口头禅,并画起了圈圈。
突然,他想出了一个有趣的题目,跑去给喜洋洋做。喜洋洋看到题目后懵逼了,但是看到潇洒哥脸上欠揍的笑容就不爽,暗想一定要做出来狠狠的打潇洒哥的脸。
于是,他以上厕所为名义跑出来用手机把题目发给了你,希望你能帮你做出来让他可以嘲讽潇洒哥。
你收到的题目如下:
平面上有n个圆,求使这n个圆两两相交(即每两个圆之间恰好有两个交点)后最多能把平面划分成多少个区域。输入描述: 一个正整数t,表示有t(1≤t≤100)组数据。 接下来t行,每行一个整数n(0≤n≤1000),代表平面内圆的个数。
输出描述: 输出共t行。每行一个正整数,表示对应的n个圆将该平面划分成的最大的区域数。
示例1
输入
3
1
2
3
输出
2
4
8
思路:我能说因为忘记0这个特例到最后也没过了。看题解后简直懊悔。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
int main()
{
int t;
long long n;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
scanf("%lld",&n);//记得long long
if(n==0)
{
printf("1\n");
}
else
{
printf("%lld\n",n*n-n+2);
}
}
}
}
5.J 王者荣耀
链接:https://ac.nowcoder.com/acm/contest/318/J
“无论何时何地,都会遵守约定”。“奋力逃吧”。“关于取下敌人性命这件事,也从不失约”。
小懒虫zmx平时最喜欢玩的游戏就是《王者荣耀》,在这款游戏中它也最喜欢百里守约这个英雄。最近,zmx准备冲国服百里,所以它开始练英雄,你有很多个时间段来练习英雄,每个时间段有一个开始时间点和结束时间点,以及可以获得的熟练度。不过现在你可以随意修改任意练习时间段的开始和结束时间点,但是你不能修改时间段的长度和获得的熟练度!由于要学习,你只能在固定时间段玩游戏,问你最多可以获得多少熟练度?
例如:你可以把[2,3),修改为[1,2)或者[3,4)等等,他们的长度都是1。
注意:对于某个时间段,不管你有没有修改,必须练完整个时间段长度才能获得熟练度!
输入描述:
第一行,三个整数n,S,T(0<n<=1000,0<S<T<1000)代表n个时间段和你能在[S,T)时间段内玩游戏。接下来n行,每行三个整数a,b(0<a<b<1000),c(0<c<1e7),用空格分开,代表时间段起始时间[a,b)和可以获得的熟练度。
输出描述:
输出一行,包括一个整数,表示zmx能获得的最大熟练度。
示例1
3 1 3
1 3 5
2 4 6
4 7 8
输出
6
示例2
输入
5 1 5
1 2 1
2 3 2
1 3 3
3 4 2
3 6 4
输出
7
思路:这题我写完WA了N次,看题解后的心情就是后悔,当事人极度后悔,我写了一周的背包,最后连一个裸的01背包都没认出,当成贪心,还思考为什么样例和自己想的例子都过了还是错了。打扰了。
#include <stdio.h>/*之后重写的代码,已AC*/
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
int x[1100],len[1100];
long long dp[100010];
int main()
{
int n,s,t,a,b;
while(scanf("%d %d %d",&n,&s,&t)!=EOF)
{
int chang=t-s;
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
{
scanf("%d %d %d",&a,&b,&x[i]);
len[i]=b-a;
}
for(int i=1; i<=n; i++)
{
for(int j=chang; j>=len[i]; j--)
{
dp[j]=max(dp[j],dp[j-len[i]]+x[i]);
}
}
printf("%lld\n",dp[chang]);
}
}
6.K 三角形
链接:https://ac.nowcoder.com/acm/contest/318/K
小明拥有n根木棍,他将这n根木棍放在桌子上排成一排,从左到右编号为1至n。
他想知道用这n根木棍能组成的周长最大的三角形的周长是多少,就在这时小红悄悄拿走了第i根木棍,现在他想知道用剩下的这n-1个木棍中的某三根能组成的周长最大的三角形的周长是多少。
.
输入描述: 第一行 包含一个整数t,表示测试用例的数量。
第二行包含2个整数,第一个是n,第二个是q,表示小红悄悄地拿走了q根木棍,每次拿走木棍的时候,她都会把之前拿走的木棍放回去(如果之前拿了木棍的话)。
第三行 包含了n个数,分别表示这n根木棍的长度ai。
接下来 q行,每行一个整数qi,表示被拿走的木棍的编号。
输出描述:
对于每个测试用例,先打印一行“Case #x:”,不包含双引号,其中x是测试用例编号(从1开始),然后对于每个测试用例,输出q行,第i行表示第qi根木棍被拿走后,剩下的n-1根木棍能组成的周长最大的三角形的周长,如果不能组成三角形则输出-1.示例1
输入
1
6 2
1 2 3 4 5 6
6
5
输出
Case #1:
12
13
备注: 1≤t≤10,1≤n≤2000 1≤q≤100, 1≤ai≤109 1≤qi≤n
思路:想得到的贪心,没想到的题解X
#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
struct node
{
int id;
long long len;
} a[maxn];
int cmp(struct node a,struct node b)
{
return a.len>b.len;
}
int main()
{
int t,n,q,x,icase=0;
long long maxx;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
scanf("%d %d",&n,&q);
for(int i=1; i<=n; i++)
{
scanf("%lld",&a[i].len);
a[i].id=i;
}
sort(a+1,a+n+1,cmp);
printf("Case #%d:\n",++icase);
while(q--)
{
maxx=-1;
scanf("%d",&x);
for(int i=1; i<=(n-2); i++)
{
int f,g,h;
if(a[i].id==x)
{
continue;
}
else if(a[i+1].id==x)
{
f=i;
g=i+2;
h=i+3;
}
else if(a[i+2].id==x)
{
f=i;
g=i+1;
h=i+3;
}
else
{
f=i;
g=i+1;
h=i+2;
}
if(a[f].len<(a[g].len+a[h].len))
{
maxx=a[f].len+a[g].len+a[h].len;
break;
}
}
printf("%lld\n",maxx);
}
}
return 0;
}
7.G LLLYYY的数字思维
链接:https://ac.nowcoder.com/acm/contest/318/G
LLLYYY很喜欢写暴力模拟贪心思维。某一天在机房,他突然抛给了队友ppq一
个问题。问题如下:
有一个函数f ():
int f(int x){
int tmp = 0;
while(x != 0){
tmp += x % 10;
x /= 10;
}
return tmp;
}
接着LLLYYY给定一个整数 c,要求在c范围内找两个整数a和b,使得a + b = c,且f(a) + f(b)的值最大。
输入描述:
采用多组输入方式。
每行输入一个整数 c (1≤c≤1012)。
输出描述:
对于每一个 c,找到一组 a,b ,使 f(a) + f(b)最大 且 a + b = c,输出这个f(a) + f(b)(0≤a,b≤c)。
链接:https://ac.nowcoder.com/acm/contest/318/G
示例1
输入
复制
35
10000000000
输出
复制
17
91
说明
在第一个样例中,可以选择 a = 17,b = 18,这样得到的f(a) + f(b)值最大为 17。
在第二个样例中, 可以选择 a = 5000000001,b = 4999999999.这样得到的f(a) + f(b)值最大为 91。
思路:题解思路:要使得f (x)尽可能的大,就是 要使得 x 中的9尽可能的多。 所以对于本题,我们可以考虑构造出一个最大的a,使得这个a满足它的每一位都是9且 a<=c,接着我们再令b = c - a,将a 和 b 分别代入 f() 中,求得最后的答案即可。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
int main()
{
long long c,a,b;
while(scanf("%lld",&c)!=EOF)
{
long long m,k;
m=c;
k=9;
while(m>=k)
{
k=k*10+9;
}
k/=10;
a=k;
b=c-a;
long long sum=0;
while(a)
{
sum+=a%10;
a/= 10;
}
while(b)
{
sum+=b%10;
b/= 10;
}
printf("%lld\n",sum);
}
}
8.D 远神的高精度
链接:https://ac.nowcoder.com/acm/contest/318/D
远神最近对高精度感兴趣,给小萌新出了道简单的除法题,a除b保留n位小数。但是越老和翔神觉得太简单了,就多加了两种操作。
翔化,结果向下取整。
越化,结果最后一位四舍五入。
输入描述:
多组输入。
第一行输入三个数a,b,n(1≤a≤100000,1≤b≤100000,0≤n≤1000)。
第二行一个字符串Xiang,Yue表示翔化和越化。
输出描述:
输出翔化或者越化的结果。
示例1
输入
2 3 5
Xiang
2 3 5
Yue
输出
0.66666
0.66667
思路:注意:保留零位小数的情况,不要输出小数点,以及进位的情况,如果是四舍 五入的话,要考虑向前进位的情况,比如结果为9.99,保留1位小数的话,应该输出 10.0。
#include<stdio.h>
using namespace std;
int ans[1005];
int main()
{
int a,b,d;
char s[10];
while(~scanf("%d%d%d%s",&a,&b,&d,s))
{
if(d==0)//不保留小数点
{
if(s[0]=='X')
{
printf("%d\n",a/b);
}
else
{
int c=a/b;
a%=b;
d=a*10/b;
printf("%d\n",d>4?c+1:c);
}
}
else
{
int k=a/b;
a%=b;
for(int i=0;i<d-1; i++)
{
a=a*10;
ans[i]=a/b;//往后除
a%=b;
}
a*=10;
ans[d-1]=a/b;//最后一位
a%=b;
int temp=a*10/b;//考虑是否进位的标准
if(temp>4&&s[0]=='Y')
{
int c=1;/*c就像flag*/
for(int i=d-1; i>=0; i--)
{
if(c==0)/*表示(四舍)五入结束*/
break;
else
{
ans[i]+=1;
c=0;
if(ans[i]>9)
{
ans[i]-=10;
c=1;
}
}
}
if(c==1)
k++;
}
printf("%d.",k);
for(int i = 0 ; i < d; i++)
{
printf("%d",ans[i]);
}
puts("");
}
}
return 0;
}
//待续