记录洛谷刷题QAQ
[COCI2011-2012#2] NAJBOLJIH 5
题目描述
给定 8 8 8 个数字 X 1 , X 2 , . . . , X 8 X_1,X_2,...,X_8 X1,X2,...,X8,从中选出 5 5 5 个数字,使得这 5 5 5 个数字的总和最大。输出这 5 5 5 个数字的和以及它们的编号。 X i X_i Xi 的编号为 i i i。
输入格式
输入共 8 8 8 行,第 i i i 行包含一个正整数 X i X_i Xi。保证所有 X i X_i Xi 互不相同。
输出格式
输出共两行。
第一行包含一个整数,表示最大的总和。
第二行包含 5 5 5 个整数,表示 5 5 5 个数的编号,按升序排序。
样例 #1
样例输入 #1
20
30
50
48
33
66
0
64
样例输出 #1
261
3 4 5 6 8
样例 #2
样例输入 #2
20
0
50
80
77
110
56
48
样例输出 #2
373
3 4 5 6 7
样例 #3
样例输入 #3
20
30
50
80
110
11
0
85
样例输出 #3
355
2 3 4 5 8
提示
【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ X i ≤ 150 1 \le X_i \le 150 1≤Xi≤150。
【说明】
本题分值按 COCI 原题设置,满分 50 50 50。
题目译自 COCI2011-2012 CONTEST #2 T1 NAJBOLJIH 5。
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
struct
{
int num;
int m;
}NUM[9];
int main()
{
for(int i = 1;i <= 8;i++)
{
scanf("%d",&NUM[i].num);
NUM[i].m = i;
}
for(int i = 1;i <= 8;i++)
{
for(int j = i+1;j <= 8;j++)
{
if(NUM[i].num < NUM[j].num)
{
NUM[i].num = NUM[j].num + NUM[i].num;
NUM[j].num = NUM[i].num - NUM[j].num;
NUM[i].num = NUM[i].num - NUM[j].num;
NUM[i].m = NUM[j].m + NUM[i].m;
NUM[j].m = NUM[i].m - NUM[j].m;
NUM[i].m = NUM[i].m - NUM[j].m;
}
}
}
long long sum = 0;
for(int j = 1;j <= 5;j++)
{
sum = sum + NUM[j].num;
for(int t = j+1;t <= 5;t++)
{
if(NUM[j].m > NUM[t].m)
{
NUM[j].m = NUM[t].m + NUM[j].m;
NUM[t].m = NUM[j].m - NUM[t].m;
NUM[j].m = NUM[j].m - NUM[t].m;
}
}
}
printf("%lld\n",sum);
for(int i = 1;i <= 5;i++)
{
printf("%d ",NUM[i].m);
}
return 0;
}
[COCI2011-2012#2] OKRET
题目描述
给定一幅 R × C R \times C R×C 的地图,其中 .
表示该格子能走,X
表示该格子不能走。判断该地图是否有死胡同。
如果一个格子满足上下左右四个格子中只有一个格子能走,那么这个格子就是死胡同。当然,不能走到地图外。
输入格式
输入的第一行包含两个正整数 R , C R,C R,C。
接下来 R R R 行,每行包含 C C C 个字符,描述这幅地图。
输出格式
如果地图中有死胡同,输出 1 1 1,否则输出 0 0 0。
样例 #1
样例输入 #1
4 3
XXX
X.X
X.X
XXX
样例输出 #1
1
样例 #2
样例输入 #2
5 5
XX.XX
X...X
.....
X...X
XX.XX
样例输出 #2
1
样例 #3
样例输入 #3
3 9
...XXX...
.X.....X.
...XXX...
样例输出 #3
0
提示
【数据范围】
对于 100 % 100\% 100% 的数据, 3 ≤ R , C ≤ 10 3 \le R,C \le 10 3≤R,C≤10。
【说明】
本题分值按 COCI 原题设置,满分 80 80 80。
题目译自 COCI2011-2012 CONTEST #2 T2 OKRET。
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
int r,c;
char m[15][15];
int main(){
scanf("%d%d",&r,&c);
for(int i=1; i<=r; ++i)
scanf("%s",m[i]+1);
for(int i=1; i<=r; ++i){
for(int j=1; j<=c; ++j){
if(m[i][j]=='.'){
int k=0;
// printf("%d %d %c %c %c %c\n",i,j,m[i-1][j],m[i+1][j],m[i][j-1],m[i][j+1]);
if(m[i-1][j]!='.') ++k;
if(m[i+1][j]!='.') ++k;
if(m[i][j-1]!='.') ++k;
if(m[i][j+1]!='.') ++k;
if(k==3){
putchar('1');
return 0;
}
}
}
}
putchar('0');
return 0;
}
[AHOI2021初中组] 超市购物
题目背景
AHOI2021 初中组 T1
你可以选择跳过背景部分。
春的一天,正是乍暖还寒时候,狂风乍起。小可可裹紧了单薄的外衣,往小雪家中赶去。
“今天真不是个出门的时候啊!”小可可感叹道。
“但是我还有东西要买……你就陪我去下超市吧?”
在超市里,小雪一共买了 23.70 元的东西,最后却只付了 20.1 元,小可可见状很疑惑。
“超市对学生有优惠呗,最后会打八五折。”
“那也不可能是这个价啊?我想想……应该是 20.145 元才对。”
“超市结算的时候最后会去分化整,也就是说,以角作为付钱的最小单位,多的零头就不要了。”
题目描述
现在,假如小可可一共买了 n n n 种类型的商品,第 i i i 种商品的单价为 a i a_i ai 元,买了 b i b_i bi 件,最后打八五折,并且舍去多出的小于一角的零头,你能不能帮他算算实际要付的钱数?
输入格式
第一行一个正整数 n n n,表示商品的种类数。
下面 n n n 行,每行一个两位小数 a i a_i ai 和一个整数 b i b_i bi,用空格隔开,分别表示第 i i i 种商品的单价和购买量。注意,输入中不会省略小数点后的零。
输出格式
仅一行,一个一位小数,表示小可可在打折并去分后要付的实际元数。注意,即使小数点后一位是 0,也要输出。
样例 #1
样例输入 #1
1
23.70 1
样例输出 #1
20.1
样例 #2
样例输入 #2
3
3.00 2
17.95 1
0.10 1
样例输出 #2
20.4
样例 #3
样例输入 #3
见附加文件的 shopping3.in。
样例输出 #3
见附加文件的 shopping3.ans。
提示
【样例 1 解释】
这就是【题目背景】中的例子。
【样例 2 解释】
小可可的原购买金额为 3.00 × 2 + 17.95 × 1 + 0.10 × 1 = 24.05 3.00 \times 2 + 17.95 \times 1 + 0.10 \times 1 = 24.05 3.00×2+17.95×1+0.10×1=24.05 元,打八五折后为 24.05 × 85 % = 20.4425 24.05 \times 85\% = 20.4425 24.05×85%=20.4425 元,去掉零头后为 20.4 20.4 20.4 元。
【数据范围与提示】
提示:如果你对浮点数不熟悉的话,请尽量利用整数完成。
- 对于 30 % 30\% 30% 的测试点,保证 n = 1 n=1 n=1;
- 对于另外 30 % 30\% 30% 的测试点,保证答案是整角;
- 对于 100 % 100\% 100% 的测试点,保证 1 ≤ n ≤ 10 1 \le n \le 10 1≤n≤10, 0.01 ≤ a i ≤ 99.99 0.01 \le a_i \le 99.99 0.01≤ai≤99.99, 1 ≤ b i ≤ 10 1 \le b_i \le 10 1≤bi≤10。
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d",&n);
double sum = 0;
while(n--)
{
double price;
int num;
scanf("%lf%d",&price,&num);
sum = sum + price * num;
}
printf("%.1lf",(int)(sum*0.85*10)/10.0);
return 0;
}
[COCI2011-2012#1] JABUKE
题目描述
Mirko 最近迷上了一款电子游戏。
这款游戏的屏幕被分成 N N N 列。在屏幕的底部,有一艘 M M M 列宽的船。游戏中,玩家可以将这艘船左右移动,但船必须时刻保持完全在屏幕内。初始时船占据屏幕最左边的 M M M 列。
有苹果会从屏幕顶部掉落。每个苹果都从顶部的 N N N 列的其中一列开始以直线掉落。当当前的苹果掉落到屏幕底部时,下一个苹果开始掉落。
如果当一个苹果掉落到底部时,船覆盖了苹果所在的列,那么我们说这个苹果是被捡起的。你的任务是在捡起所有苹果的前提下,最小化船移动的距离。
输入格式
第一行包含两个以空格分隔的整数 N , M N,M N,M。
第二行包含一个整数 J J J,表示将要掉落的苹果的个数。
接下来 J J J 行的第 i i i 行包含一个整数,表示第 i i i 个苹果将要从哪一列开始掉落。
输出格式
输出一行一个整数,表示最小的船移动的距离。
样例 #1
样例输入 #1
5 1
3
1
5
3
样例输出 #1
6
样例 #2
样例输入 #2
5 2
3
1
5
3
样例输出 #2
4
提示
【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ M < N ≤ 10 1 \le M < N \le 10 1≤M<N≤10, 1 ≤ J ≤ 20 1 \le J \le 20 1≤J≤20。
【说明】
本题分值按 COCI 原题设置,满分 50 50 50。
题目译自 COCI2011-2012 CONTEST #1 T1 JABUKE。
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
int main()
{
int n, m;
scanf("%d%d",&n,&m);
int left = 1, right = m;
int num;
scanf("%d",&num);
int sum = 0;
for(int i = 0;i < num;i++)
{
int a;
scanf("%d",&a);
if(right >= a&&a >= left)
{
sum = sum + 0;
}
if(right < a)
{
sum = sum + a - right;
right = a;
left = right - m +1;
}
if(a < left)
{
sum = sum + left - a;
left = a;
right = left + m - 1;
}
}
printf("%d\n",sum);
return 0;
}
[COCI2010-2011#5] GLJIVE
题目描述
在超级马里奥面前有 10 10 10 个蘑菇,排成一排。每挑选一个蘑菇就奖励一些分数。
超级马里奥必须按蘑菇出现的顺序挑选蘑菇,但并不是要求把他们都采集出来——他的目标是得分尽可能接近 100 100 100。
如果存在两个同样接近 100 100 100 的数字(例如 98 98 98 和 102 102 102),马里奥会选择较大的那个(这里是 102 102 102)。
帮助超级马里奥,告诉他他能得到多少分。
输入格式
输入共 10 10 10 行,每一行包含一个正整数 A i A_i Ai,表示挑选当前蘑菇所获得的分数,按照马里奥挑选蘑菇的顺序排列。
输出格式
输出共 1 1 1 行,一个整数,表示马里奥能得到的分数。
样例 #1
样例输入 #1
10
20
30
40
50
60
70
80
90
100
样例输出 #1
100
样例 #2
样例输入 #2
1
2
3
5
8
13
21
34
55
89
样例输出 #2
87
样例 #3
样例输入 #3
40
40
40
40
40
40
40
40
40
40
样例输出 #3
120
提示
【样例解释#1】
马里奥选择第 10 10 10 个蘑菇,得到 100 100 100 分。
【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ A i ≤ 100 1\le A_i\le 100 1≤Ai≤100。
【说明】
本题分值按 COCI 原题设置,满分 30 30 30。
题目译自 COCI2010-2011 CONTEST #5 T1 GLJIVE。
代码如下:
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
int max(int a,int b)
{
if(a > b)
return a;
else
return b;
}
int n=10,t,a,ans;
int main() {
for(int i=1;i<=n;i++){
scanf("%d",&t);
a+=t;
if(abs(ans-100)>abs(a-100))ans=a;//取更接近100的那一个
if(abs(ans-100)==abs(a-100))ans=max(ans,a);//一样近,取更大的那一个
if(a>100)break;
}
printf("%d\n",ans);
return 0;
}