练习2

A - 鸡尾酒疗法

鸡尾酒疗法,原指 “高效抗逆转录病毒治疗”(HAART),由美籍华裔科学家何大一于1996年提出,是通过三种或三种以上的抗病毒药物联合使用来治疗艾滋病。该疗法的应用可以减少单一用药产生的抗药性,最大限度地抑制病毒的复制,使被破坏的机体免疫功能部分甚至全部恢复,从而延缓病程进展,延长患者生命,提高生活质量。人们在鸡尾酒疗法的基础上又提出了很多种改进的疗法。为了验证这些治疗方法是否在疗效上比鸡尾酒疗法更好,可用通过临床对照实验的方式进行。假设鸡尾酒疗法的有效率为 x,新疗法的有效率为 y,如果 y−x 大于 5%,则效果更好,如果 x−y 大于 5%,则效果更差,否则效果差不多。下面蒜头君给出 n 组临床对照实验,其中第一组采用鸡尾酒疗法,其他 n−1 组为各种不同的改进疗法。请写程序判定各种改进疗法效果如何。输入格式第一行为整数 n(1 Sample Input
5
125 99
112 89
145 99
99 97
123 98
Sample Output
same
worse
better
same
思路:题目很水。

# include 
using namespace std;
int main (void)
{
	int n;
	double a,b,c,d,e,f;
	cin>>n;
	scanf("%lf%lf",&d,&e);
	f=e/d;
	for(int i=0;i<n-1;i++)
	{
		scanf("%lf%lf",&a,&b);
		c=b/a;
		if(c-f>0.05) printf("better\n");
		else if(f-c>0.05) printf("worse\n");
		else printf("same\n");
	}
	return 0;
 } 

B - 构造三角形

蒜头君有两根木棍,长度分别为整数 a、b,他想找第三根木棍来组成一个三角形,可供他选择的木棍的长度都是 整数,请问他可以选的木棍最长是多少?提示:三角形的两边之和一定大于第三条边。输入格式一行两个整数 a,b(1≤a,b≤100) ,表示蒜头君已有的两根木棍的长度。
输出格式
一行一个整数,表示第三根木棍长度的最大值数据规模与约定对于 100% 的数据,1≤a,b≤100 。
Sample Input
2 4
Sample Output
5
Sample Input 2
3 3
Sample Output 2
5
思路:这个只要抓住两边之和大于第三边就好了

# include 
using namespace std;
int main (void)
{
    int a,b;
    while(~scanf("%d%d",&a,&b))
    {
    	printf("%d\n",a+b-1);
	}
	return 0;
 } 

C - 机器人走方格

有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去。机器人有一个初始能量,每个格子对应一个整数Ai,表示这个格子的能量值。如果Ai > 0,机器人走到这个格子能够获取Ai个能量,如果Ai < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了。问机器人最少需要有多少初始能量,才能完成整个旅程。
例如:n = 5。{1,-2,-1,3,4} 最少需要2个初始能量,才能从1号走到5号格子。途中的能量变化如下3 1 0 3 7。
Input
第1行:1个数n,表示格子的数量。(1 <= n <= 50000) 第2 - n + 1行:每行1个数Ai,表示格子里的能量值(-1000000000 <= Ai <= 1000000000)
Output
输出1个数,对应从1走到n最少需要多少初始能量。
Sample Input
5
1
-2
-1
3
4
Sample Output
2
思路:这道题就是用一个数组,标记每走一步的能量变化,找到能量最低的那个点,只要我的初始能力加这个最低点等于零就好了

# include 
using namespace std;
int main (void)
{
    long long n,a[50005],sum[5005],min;
    cin>>n;
    for(int i=0,j=0;i<n;i++)
    {
    	scanf("%lld",&a[i]);
	}
	sum[0]=min=a[0];
    for(int i=1;i<n;i++)
    {
    	sum[i]=sum[i-1]+a[i];
	}
	
	for(int i=1;i<n;i++)
	{
		if(sum[i]<min) min=sum[i];
	}
	printf("%lld",-min);
	return 0;
 } 

D - RGB

We have a string S of length N consisting of R, G, and B.Find the number of triples (i, j, k) (1≤i 1.Si≠Sj, Si≠Sk, and Sj≠Sk.
2.j−i≠k−j.
Constraints
1≤N≤4000
S is a string of length N consisting of R, G, and B.
Input
Input is given from Standard Input in the following format:
N
S
Output
Print the number of triplets in question.
Sample Input 1
4
RRGB
Sample Output 1
1
Sample Input 2
39
RBRBGRBGGBBRRGBBRRRBGGBRBGBRBGBRBBBGBBB
Sample Output 2
1800
思路:这道题的大意就是从输入的字符串中凑出RGB这样子。然后还要满足两个条件。我的想法就是现把所有的可能情况全部列出来。所有的可能情况就是R的数量乘以G的数量乘以B的数量。然后再把满足条件二的情况算出来再减去就好了。而算条件二可以用等差数列来看,设置一个公差d。这样子就可以了

# include 
using namespace std;
const int N=4005;
char s[4005];
long long ans;
int main(void)
{
	int n,a[3]={};//我需要用a的数组来标记RGB的数量
	scanf("%d",&n);
	scanf("%s",s+1);
	for(int i=1;i<=n;i++)
	{
		if(s[i]=='R') a[0]++;
		else if(s[i]=='G') a[1]++;
		else a[2]++;
	} 
	ans=(long long )a[0]*a[1]*a[2];//ans代表全部的情况
	for(int i=1;i<n;i++)
	{
		for(int d=1;i+d+d<=n;d++)//d是公差
		{
			if((s[i]^s[i+d]^s[i+d+d])==('R'^'G'^'B')) --ans;//条件满足的话,那就自减一
		}
	}
	printf("%lld\n",ans);
	return 0;
}

E - 田忌赛马

赛马是一古老的游戏,早在公元前四世纪的中国,处在诸侯割据的状态,历史上称为 “战国时期”。在魏国作官的孙膑,因为受到同僚庞涓的迫害,被齐国使臣救出后,到达齐国国都。赛马是当时最受齐国贵族欢迎的娱乐项目。上至国王,下到大臣,常常以赛马取乐,并以重金赌输赢。田忌多次与国王及其他大臣赌输赢,屡赌屡输。一天他赛马又输了,回家后闷闷不乐。孙膑安慰他说:“下次有机会带我到马场看看,也许我能帮你。”孙膑仔细观察后发现,田忌的马和其他人的马相差并不远,只是策略运用不当,以致失败。比赛前田忌按照孙膑的主意,用上等马鞍将下等马装饰起来,冒充上等马,与齐王的上等马比赛。第二场比赛,还是按照孙膑的安排,田忌用自己的上等马与国王的中等马比赛,在一片喝彩中,只见田忌的马竟然冲到齐王的马前面,赢了第二场。关键的第三场,田忌的中等马和国王的下等马比赛,田忌的马又一次冲到国王的马前面,结果二比一,田忌赢了国王。不过多久,国王又找到田忌赛马,这次国王和田忌都准备了 n 匹马,每匹马都有恒定的速度,所以速度大的马一定比速度小的马先到终点(没有意外!!)。每场比赛国王会先出一匹没有出战过的马,然后田忌再选择一匹没有出战过的马进行对战。这次田忌找你帮忙,你最多能帮田忌赢得几场比赛(平局不算赢)。
输入格式
输入数据包含三行。
第一行输入
n(1≤N≤1000),表示马的数量。第二行有 n 个整数,即田忌的 n 匹马的速度。第三行有 n 个整数,即国王的 n 匹马的速度。马的速度大于 0 小于等于 1000。
输出格式
输出通过你的精心安排,最多能赢得多少场比赛。
Sample Input
10
9 2 6 2 8 2 4 9 6 1
8 2 2 1 8 10 9 3 1 10
Sample Output
7
思路:这道题我第一次的想法就是对两组数据进行排序,然后找到国王马中速度小于田忌的最快的马的那匹马,标记。然后一次比较就可以了,可惜过不去。第二次我有换了个方向,依然是排序,从数组的第一个开始,比较,遇道比不过的,把国王的数组减一,等于拿差马顶好马。

# include 
#include 
#include 
using namespace std;
int main()
{
	int n,i,win,firs,secs,firf,secf,tian[5005],guo[5005]; 	    
	scanf("%d",&n);
	firs=secs=win=0;
	firf=secf=n-1;
	for (i=0;i<n;i++)
	{
		scanf("%d",&tian[i]);
	}
	for (i=0;i<n;i++)
	{
		scanf("%d",&guo[i]);
	}
	sort(tian,tian+n);//排序 
	sort(guo,guo+n);
	for (i=0;i<n;i++)
	{
		if (tian[firs]>guo[secs])
		{
			firs++;
			secs++;
			win++;
		}
		else if (tian[firs]<guo[secs])
		{
			firs++;
			secf--;
		}
		else 
		{
			if (tian[firf]>guo[secf])
			{
				firf--;
				secf--;
				win++;
			}
			else
			{
				firs++;
				secf--;
			}
			}
		}
	   cout<<win;
  	return 0; 
}

F - 碉堡

约翰用沙子建了一座城堡。正如所有城堡的城墙,这城墙也有许多枪眼,两个相邻枪眼中间那部分叫作“城齿”。城墙上一共有 N (1≤N≤25000) 个城齿,每一个都有一个高度 Mi (1≤Mi≤105)。现在约翰想把城齿的高度调成某种顺序下的 Bi (1≤Bi≤105)。一个城齿每提高一个单位的高度,约翰需要 X (1≤X≤100) 元;每降低一个单位的高度,约翰需要 Y (1≤Y≤100)元,问约翰最少可用多少钱达到目的。
输入格式
第一行三个整数
N,X,Y。
接下来 N 行,每行两个整数 Mi,Bi。输出格式一个整数,表示最少的花费。
Sample Input
3 6 5
3 1
1 2
1 2
Sample Output
11
思路:其实这道题的题意就是把一个毫无关系的数组花费最小的代价变成另外一个数组。所以只需要对两个数组进行排序,然后逐位比较大小就好啦

# include 
#include
#include
#define N 25001
using namespace std;
int n,m[N],b[N],x,y,ans;
inline int f(int a,int z)
{return a>z?(a-z)*y:(z-a)*x;}
int main()
{
    scanf("%d%d%d",&n,&x,&y);
    for(int i=0;i<n;i++) scanf("%d%d",&m[i],&b[i]);
    sort(m,m+n);sort(b,b+n);
    for(int i=0;i<n;i++) ans+=f(m[i],b[i]);
    printf("%d",ans);
}

G - 大小写规范

宁姚最近要过生日了,陈平安打算写一张生日贺卡发给她,祝她生日快乐!
他想出来一个句子(全部由英文字母组成),可是由于想的时候过于犹豫,最后写出来时由大写字母与小写字母组成。为了表示尊敬,所以要把字符串前面开头部分改为大写,后面全部都为小写。你可以把一个大写字符改为小写字符,把一个小写字符改为大写字符。
现在问,最少修改多少个字符的状态,你可以把字符串改为前面是大写字符,后面是小写字符的字符串。
当然,前面的大写字符个数可以为0,后面的小写字符个数也0
Input
一个由小写字符或大写字符组成的字符串,大小不超过 105.
Output
一个数字,表示最小的修改次数 fancy.
Example
Input
PRuvetSTAaYA
Output
5
Input
OYPROSTIYAOPECHATALSYAPRIVETSTASYA
Output
0
Input
helloworld
Output
0
这题还不会,等想出来再给题解。
那道田忌赛马的题目如果可以做出我第一次想法的正确题解的,请私信告诉我一下,或者评论。或者告诉我我一下,我想错在哪里。

你可能感兴趣的:(练习)