问题 A: 卷王之争
问题描述:
身为新一届的大佬,H同学和T同学两个人开始竞争卷王之位。
H同学说:我每周抽a/b的时间用来学习,我是卷王!
T同学说:我每周x/y的时间都在学习,比你多,我才是卷王!
H同学不服气,反驳道:明明我比你学习时间多,我才是!
现在,他们两个想知道,到底谁的学习时间多。
输入
一行四个非负整数,a,b,x,y
(a<=b,x<=y ,< a,b,x,y <= 100 000 000, b , y不等于0)
输出
如果小H的学习时间多,输出"H is juanwang!" ;
如果小T的学习时间多,输出"T is juanwang!" ;
如果两人学习时间一样多,输出"We are juanwang!" ;
(输出不带引号)
样例输入
1 2 3 4
样例输出
T is juanwang!
原因分析:
1. 第一次开了的精度太大了 (1e-6),应该尽量开大点 1e-20;
2. double不能直接判等号.(由于浮点型的精度是有限的,经过运算就可能存在舍入误差)
3.还可以通过 通分直接比较分子大小,避免了上述问题.(更精准)
解决方案:
1.精度确定个范围
#include <iostream>
#include <algorithm>
#include <cmath>#define double long doubleconst double eps = 1e-20 ;int dcmp(double x,double y){if(fabs(x - y ) < eps) return 0 ;if(x < y) return -1;return 1 ;
}
int main()
{double a, b , x , y ;scanf("%d%d%d%d" ,&a ,&b ,&x ,&y) ;double s = a/b ;double u = x/y ;if(dcmp(s,u) > 0)printf("H is juanwang!\n") ;else if(dcmp(s,u) < 0)printf("T is juanwang!\n") ;elseprintf("We are juanwang!\n") ;return 0 ;}
2. 通分
#include <iostream>int main()
{long long a , b , x , y ;scanf("%d%d%d%d",&a,&b,&x,&y) ;a*= y ;x*= b ;if(a > x)printf("H is juanwang!\n") ;else if(a < x)printf("T is juanwang!\n") ;elseprintf("We are juanwang!\n") ;return 0;
}
问题 B: 纸牌游戏(待更新)
问题描述:
众所周知,acmer们打纸牌,输了是要写题解的。
S学长因为打纸牌输了很多题解,现在S学长想玩一个纸牌游戏挑战新生。
游戏规则是这样的:
一副纸牌有54张,这个游戏我们暂且不要大小王,则游戏中我们有52张纸牌可以使用,共四种花色,每种花色13张纸牌。
游戏开始两个人轮流取走纸牌,规定每人每次可以取走任意花色的纸牌最多n张,并且每次取走的这些纸牌只能是同种花色,(不必与对方取的纸牌花色一样),不可以不取;
最后没有纸牌可以取的一方为失败者。
S学长想让让新生,所以让对方可以先取。
因为S学长是绝顶聪明的,为了能赢过他,必须采取的是最优策略。
输入:
一个整数n(1<= n <=13),代表每次可以取走的最多纸牌数。
输出:
如果新生可以赢得s学长,输出“%%%” ;
如果新生输了,输出“tql” ;
样例输入:
10
样例输出:
tql
原因分析:
解决方案:
#include <stdio.h>int main()
{printf("tql") ;return 0;
}
问题 C: 签到时间
问题描述:
出题人说是时候要给新生赛出一道签到题了,但她并不想让所有的新生都能签到()。
已知出题人很喜欢偶数,所以出题人想要在所有参赛人中选偶数个同学让他们签到成功。
现有n个参赛人,编号分别为1~n。
现在出题人开始挑选m个同学了。(m > 0)
若选出的m个同学数量是偶数,她将视为这是一个好方案;如果是奇数,则是一个坏方案。
出题人现在想知道好方案与坏方案的差是多少。
输入:
一个整数n,代表参赛人数。(n <= 1e6)
输出:
输出好方案与坏方案的差。
样例输入:
4
样例输出:
-1
原因分析:
奇数项的系数和即 C(n,1)+C(n,3)+C(n,5)...... = 偶数项的系数和 C(n,0)+C(n,2)+C(n,4)......
而题目要求 C(n,2)+C(n,4)...... - [ C(n,1)+C(n,3)+C(n,5)...... ]
即 偶数项少了个 C(n,0) 即最后结果为 -1
解决方案:
#include <stdio.h>int main()
{printf("-1\n") ;return 0;
}
问题 D: 干饭时间
问题描述:
小R作为一个资深的干饭人,他每次都会抓紧每一分钟的时间去买所有想吃的东西。
这天小R想买的东西有n种,买这n种东西所需要排队等待的时间分别为a1 , a2 , a3 ... an ;
由于,小R又是一个非常懒惰的人,他同一时间最多只会去买两种东西,并且,他需要在买的东西做好之前赶回来,不然他要重新排队购买。
例如,买蛋糕的时间为15min,买饮料的时间为10min,买零食的时间为4min,小R可以去买了蛋糕之后,利用等待的时间去买饮料;虽然买完饮料后,还有5min可以去买零食,但是为了简化问题,小R不会去买零食,而是赶回去等在蛋糕做好之后,他再去买零食,这样,他就省出了单独去买饮料的时间,总时间为15min+4min=19min;
再例如,买蛋糕的时间为15min,买饮料的时间也是15min,当他去买蛋糕时,同时他就不能去买饮料了,因为这样他就不满足在蛋糕做好之前赶回来,所以总时间为30min。
小R是个非常聪明的人,所以他会运用他的智慧,找到买完这些东西要用的最短的时间。
请你计算,聪明的小R买完所有他想吃的东西,所用的最短时间。
输入:
一行一个整数n ( n <= 1000 ),代表小R想买的东西的个数。
n个整数a1 , a2 , a3 ... an ,均不大于1000;
输出:
一行一个整数,代表最短的时间。
样例输入:
5 4 1 5 2 3
样例输出:
9
原因分析:
1.如果数据个数为奇数,则需要特别处理下最后一个数(经过排序后的最后一个数,即最小数)
即 a[n]=0; 当然个数为偶数也不影响.
2. ans+=a[i]; 放到第二个for前,要不然 如果数据为
3
5 5 5
只会输出 5即只加了最后一个.
解决方案:
#include<bits/stdc++.h>
using namespace std;
int n,a[10000],b[10000];
bool cmp(int a,int b){return a>b;}
int main()
{int i,j,ans=0,mid;cin>>n;for(i=0;i<n;i++)cin>>a[i];a[n]=0;sort(a,a+n,cmp);for(i=0;i<n;i++){if(b[i]==1)continue;else{ans+=a[i];for(j=i+1;j<n+1;j++){if(a[i]>a[j]&&b[i]!=1&&b[j]!=1){b[i]=1;b[j]=1;break;}}}}cout<<ans;}
问题 F: 周赛榜单
问题描述:
周赛的榜单出来啦,21届的成绩真的是太好了。
某人想从新生榜单里选m个人,让他们成为"winner" ;
于是,好奇的某人想知道,选出的这m个人成绩之和最大是多少。
于是,她出了个赛题,让新生们自己算。
输入:
一个整数n(n <= 1e6),代表参加新生赛的新生数。
接下来按榜单顺序输入n个新生的成绩。成绩不大于100。
一个整数t(t <= 1e6),代表某人询问的次数。
接下来t个整数。
输出:
每次询问,给出前m个新生的成绩之和。
样例输入:
5 10 7 5 4 3 2 1 3
样例输出:
10 22
原因分析:
1. 超过1e6 的数据 不能用cin(除非关闭输入输出流),或用scanf
解决方案:
#include<bits/stdc++.h>using namespace std;
#define ll long long
ll s[1000050],n,a[1000050];
int main()
{ll t,x;scanf("%lld",&n);for(int i=1;i<=n;i++){scanf("%lld",&a[i]);s[i]=s[i-1]+a[i];}scanf("%lld",&t);while(t--){scanf("%lld",&x);printf("%lld\n",s[x]);}return 0;
}
问题 H: 三角图形
问题描述:
阿H有六根棍子。
阿H很喜欢三角形,所以,他想知道能不能用这六根棍子组成两个三角形?
为了问题更容易一点,阿H把从大到小排好序的棍子拿给你,请你帮他解决问题。
输入:
六个数,代表阿H六根棍子的长度。(长度小于100)
输出:
能组成三角形, 输出"Yes" ;
反之,输出"No" ;
样例输入:
1 1 1 1 1 1
样例输出:
Yes
原因分析:
思路基本没错,就是最后寻找剩下的三根木棍 思路出现问题,可以直接将下标不等于 i,j,k的数据存到另一个数组中.
解决方案:
1. 把剩下的数存到另一个数组里(简单方法)
#include <iostream>
#include <cstdio>int is_right(int a , int b , int c)
{if(c+b > a)return 1 ;return 0 ;
}int main()
{int a[10] ;for(int i = 0 ; i < 6 ; i++)scanf("%d", &a[i]) ;int flag = 0 ;for(int i = 0 ; i < 6 ; i++)for(int j = i+1 ; j < 6 ; j++)for(int k = j+1 ; k < 6 ; k++){int b[5] ;int c = 0 ;for(int p = 0 ; p < 6 ; p++)if(p != i && p != j && p != k)b[c++] = a[p] ;if(is_right(a[i] , a[j] , a[k])==1 && is_right(b[0] , b[1] , b[2])==1){flag = 1 ;break ;}}if(flag == 0)printf("No\n") ;elseprintf("Yes\n") ;return 0 ;
}
2.直接利用3个for找剩下的三根
#include<bits/stdc++.h>using namespace std;
#define ll long long
int main()
{int a[7],i,j,k;for(i=0;i<6;i++)cin>>a[i];for(i=0;i<6;i++){for(j=i+1;j<6;j++){for(k=j+1;k<6;k++){if(a[k]+a[j]>a[i]){int x,y,z;for(x=0;x<6;x++){for(y=x+1;y<6;y++){for(z=y+1;z<6;z++){if(x!=i&&x!=j&&x!=k&&y!=i&&y!=j&&y!=k&&z!=i&&z!=j&&z!=k){if(a[y]+a[z]>a[x]){cout<<"Yes";return 0;}}}}}}}}}cout<<"No";return 0;
}
部分转载cx学姐 %%%cx聚聚
2021HAUT_新生周赛lcx专场(三)_lichenx_的博客-CSDN博客