4 兼容任务
设有n个任务,其中每个任务有一个起始时间si和一个结束时间ei,且si<ei,同一时间只能完成一个任务。如果选择了任务i ,则它在时间区间 [si ,ei) 内占用资源。若区间 [si ,ei) 与区间 [sj, ej)不相交,则称任务 i 与任务 j 是相容的。那么,对于给定的任务时间区间,能互相兼容的最大任务个数是多少呢?
输入格式
第一行一个整数n (1<=n<=1000) ;
接下来n行,每行两个整数si 和 ei。
输出格式
互相兼容的最大任务个数。
输入样例
4
1 3
4 6
2 5
1 7
输出样例
2
Accepted
#include <cstring>
#include<algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <stdio.h>
#include <string.h>
using namespace std;
struct range{
int l;
int r;
}a[1000];
bool cmp(range a,range b){
return a.r<b.r;
}
int main(){
int n,num=1,i;
int t;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d %d",&a[i].l,&a[i].r);
}
sort(a,a+n,cmp);
t=a[0].r;
for(i=1;i<n;i++){
if(a[i].l>=t){
num++;
t=a[i].r;
}
}
printf("%d
",num);
return 0;
}
5 致死一击
Kunkun最近热爱rpg闯关游戏,经常带着他的舍友打各种boss。但是随着舍友装备的逐渐升级,kunkun发现他给予boss最后一击的机会越来越少(给boss最后一击的玩家稀有装备爆率会大幅度提升)。所以kunkun联系到了一个神秘人,他可以利用时停来让boss躲过舍友的攻击,每次时停只能躲避一次攻击。 假设kunkun和他的舍友都采取轮流攻击战术(kunkun率先攻击,kunkun的攻击力为a;舍友的攻击力为b,玩家每次都只进行一次攻击)去刷n个boss。如果最多只能使用k次时停,那么kunkun能造成致死伤害的boss最多有几个?
输入格式
输入共两行。
第一行包括4个正整数 n,a,b,k (1≤n≤2*1e5, 1≤a,b,k≤1e9),n表示boss的数量,a为kunkun的攻击力,b为kunkun舍友的攻击力,k为时停的最大次数。
第二行输入n个正整数h1,h2,…,hn (1≤hi≤1e9),表示每个boss的血量。
输出格式
输出一个整数,即kunkun造成致死伤害的boss的最大个数。
输入样例1
6 2 3 3
7 10 50 12 1 8
输出样例1
5
输入样例2
6 2 3 3
7 10 50 12 1 8
输出样例2
5
输入示例3
7 4 2 1
1 3 5 4 2 7 6
输出示例3
6
这题题意有一个很重要的一点就是,每只怪都是独立的,也就是说,当每一只怪死后,下一只怪先手依然是kunkun,所以,我们可以通过分别算出杀死一只怪需要多少次时停,然后再从小到大进行排序,最终得出结果。
Accepted
#include <cstring>
#include<algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(){
int n,a,b,k,i,j;
int h;
int num=0;
int count[1000000]={0};
scanf("%d %d %d %d",&n,&a,&b,&k);//n表示boss的数量,a为kunkun的攻击力,b为kunkun舍友的攻击力,k为时停的最大次数。
for(i=1;i<=n;i++){
scanf("%d",&h);
while(1){
h-=a;
if(h<=0) break;
h-=b;
if(h<=0) {
h+=b;
count[i]++;
}
}
}
sort(count+1,count+1+n);
for(i=1,j=0;i<=n;i++){
j+=count[i];
if(j>k) break;
num++;
}
printf("%d
",num);
return 0;
}
#include <cstring>
#include<algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(){
int n,a,b,k,i,j;
int h;
int num=0;
int count[100000]={0};
scanf("%d %d %d %d",&n,&a,&b,&k);//n表示boss的数量,a为kunkun的攻击力,b为kunkun舍友的攻击力,k为时停的最大次数。
for(i=1;i<=n;i++){
scanf("%d",&h);
h%=(a+b);//注意这里
if(h==0) h+=(a+b);//注意这里
while(1){
h-=a;
if(h<=0) break;
h-=b;
if(h<=0) {
h+=b;
count[i]++;
}
}
}
sort(count+1,count+1+n);
for(i=1,j=0;i<=n;i++){
j+=count[i];
if(j>k) break;
num++;
}
printf("%d
",num);
return 0;
}
7 德州扑克
最近,阿夸迷于德州扑克。所以她找到了很多人和她一起玩。由于人数众多,阿夸必须更改游戏规则:
- 所有扑克牌均只看数字,不计花色。
- 每张卡的值为1、2、3、4、5、6、7、8、9、10、11、12、13 中的一种(对应A,2、3、4、5、6、7, 8、9、10,J,Q,K)
- 每位玩家从一副完整的扑克牌(没有大小王)中抽出五张扑克牌,可能出现的手牌的值从低到高排列如下:
- 高牌:不包含以下牌的牌。对于都是高牌的牌,按照五张牌的值的和进行从大到小排序。
- 对子:手中的5张牌中有2张相同值的牌。对于都拥有对子的牌,按构成该对子的牌的值进行从大到小地排序。如果这些都相同,则按手牌中余下3张牌的值的和进行从大到小排序。
- 两对:手中拥有两对不同的对子。对于都包含两对的手牌,按其最高对子的值进行从大到小排序。如果最高对子相同,则按另一个对子的值从大到小地进行排序。如果这些值相同,则按剩余牌的值从大到小地进行排序。
- 三条:手中拥有3张相同值的牌。对于都包含三条的手牌按构成三条的牌的值进行从大到小地排序。如果这些值相同,则按剩余牌的值从大到小地进行排序。
- 满堂红:手中拥有一个三条和一个对子。同理,先按三条大小排序,如果三条大小相同,则按对子大小进行排序。
- 四条:手中拥有4张相同值的牌。对于都包含四条的手牌按构成四条的牌的值进行从大到小地排序。如果这些值相同,则按剩余牌的值从大到小地进行排序。
- 顺子:手中拥有5张连续值的卡。对于都包含顺子的手牌按顺子最大的牌进行排序。
- 皇家同花顺:手中拥有10到A(10、J、Q、K、A)。是最大的手牌!
现在,阿夸已经知道了每个人的手牌,她想要知道所有人的排名列表。如果玩家的手牌大小相等,则按玩家名字的字典序输出。保证没有重复的名字。你能帮帮她吗?
输入格式
第一行包含一个正整数 N (1<=N<=100000) ,表示玩家的人数。
接下来 N 行,每行包含两个字符串:m (1<=|m|<=10 ) ,表示玩家的名字;s (1<=|s|<=10),表示玩家的手牌。
输出格式
输出 N个玩家的排名列表。
输入样例
3
Alice AAA109
Bob 678910
Boa 678910
输出样例:
Boa
Bob
Alice
Accepted
#include <cstring>
#include<algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
//level代表优先级 level1 > level2 > level3 > level4
using namespace std;
struct player{
string name;
int level1=0;
int level2=0;
int level3=0;
int level4=0;
}p[100005];
int change[100];//每张牌出现的次数
int poker[100];//每张牌对应的数值
int sum;
void judge(int a){ // a表示第几个玩家
int i,j;
int flag=0;
sort(poker+1,poker+6);//把五张手牌大小从小到大排序
//皇家同花顺
if(change[1]==1&&change[10]==1&&change[11]==1&&change[12]==1&&change[13]==1){
p[a].level1=8;
return ;
}
//顺子
for(i=2;i<=5;i++){
if(poker[i]!=poker[i-1]+1) {
flag=1;
break;}
}
if(flag==0) {
p[a].level1=7;
p[a].level2=poker[5];
return ;
}
//四条
for(i=1;i<=2;i++){
if(poker[i]==poker[i+3]){
p[a].level1=6;
p[a].level2=poker[i];
p[a].level3=sum-4*poker[i];
return ;
}
}
//满堂红
if(poker[1]==poker[2]&&poker[3]==poker[5]){
p[a].level1=5;
p[a].level2=poker[3];
p[a].level3=poker[1];
return ;
}
if(poker[1]==poker[3]&&poker[4]==poker[5]){
p[a].level1=5;
p[a].level2=poker[1];
p[a].level3=poker[4];
return ;
}
//三条
for(i=1;i<=3;i++){
if(poker[i]==poker[i+2]){
for(j=1;j<=5;j++)
if(poker[j]!=poker[i])
{
p[a].level1=4;
p[a].level2=poker[i];
p[a].level3=sum-3*poker[i];
return ;
}
}
}
//两对
for(i=1;i<=13;i++){
if(change[i]==2){
for(j=1;j<=13;j++){
if(change[j]==2 && i!=j){
p[a].level1=3;
if(i>j){
a[p].level2=i;
a[p].level3=j;
}
else{
a[p].level2=j;
a[p].level3=i;
}
a[p].level4=sum-2*i-2*j;
return;
}
}
//对子
p[a].level1=2;
p[a].level2=i;
p[a].level3=sum-2*i;
return ;
}
}
//高牌
p[a].level1=1;
p[a].level2=sum;
return ;
}
bool cmp(player a,player b){
if(a.level1!= b.level1) return a.level1 > b.level1;
if(a.level2!= b.level2) return a.level2 > b.level2;
if(a.level3!= b.level3) return a.level3 > b.level3;
if(a.level4!= b.level4) return a.level4 > b.level4;
else return a.name < b.name;
}
int main(){
int n;
int i,j;
char ch; //读入的每张牌;
cin >> n;
for(i=1;i<=n;i++){
memset(change,0,sizeof(change)); //每次输入玩家的手牌前,h出现次数清零
cin >> p[i].name;
getchar();
for(j=1;j<=5;j++){
cin >> ch;
if(ch=='A') {
poker[j]=1;
change[1]++;
}
else if(ch=='J') {
poker[j]=11;
change[11]++;
}
else if(ch=='Q') {
poker[j]=12;
change[12]++;
}
else if(ch=='K') {
poker[j]=13;
change[13]++;
}
else if(ch=='1') {//手牌为10
change[10]++;
poker[j]=10;
cin >> ch;
}
else {
poker[j]=ch-'0';
change[poker[j]]++;}
}
sum=0;
for(j=1;j<=5;j++){
sum+=poker[j];
}
judge(i);
}
sort(p+1,p+1+n,cmp);
for(i=1;i<=n;i++){
cout << p[i].name << endl;
}
return 0;
}