OJ某些代码

问题1:敢敢单单的斐波那契数列

Description
大家都知道斐波那契数列吧!它的定义是这样的:斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n−1)+F(n−2) (n≥3,n∈N∗)。
这题的题意也很简单,给你一个正整数n(1≤n≤107),让你输出斐波那契数列的第n项~由于答案较大,所以输出答案对109+7取模后的数。

Input
多组读入,保证不超过10组,每组一个正整数n(1≤n≤107)。

Output
斐波那契数列的第n项,答案对109+7取模。

Samples
Input Copy
1
Output
1
Hint
请留意本题使用空间限制。

#pragma GCC optomize(2)
#pragma G++ optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=1e7+7;
int s[maxn];
int main()
{
   ll n,i;
   s[1]=s[2]=1;
   for(i=3;i<=maxn;i++)
   {
      s[i]=(s[i-1]+s[i-2])%mod;
   }
   while(cin>>n)
   {
      cout<<s[n]%mod<<endl;
   }
   return 0;
}

注意本题用递归解决会超时,所以可以选择打表做(即先将所有结果先算出来,用数组进行存储)。

问题2:HJ又种花啦

Description
HJGG现在有一个大小为 n(米)*m(米)的矩形花园。

由于HJGG有强迫症,所以这片花园被划分n∗m个为1*1(平方米)的方格。

现在,HJ想在这片花园上种好多种花,并且他想要相邻的格子上种不同的花~(解释:相邻指的是上下左右四个方向相邻)

添加解释。相邻的格子上种不同的花指的是:一个位置和他上下左右四个方向位置的颜色不同,对于上下左右这四个位置,是可以相同的。
由于HJ被集训队小可爱蕾酱缠着不能脱身,所以想要你来帮帮他~
如果可以满足HJ哥哥的要求,就告诉他“Beautiful flowers!”,如果不可以就告诉他“Oh! My poor HJ!”(输出均不含双引号)
谁让大家都不能拒绝蕾蕾呢!

Input
输入仅一行三个整数n,m,k(1≤n,m,k≤105),分别表示HJGG花园的长和宽,HJGG拥有的花的种类数

Output
输出一行你要告诉Hj的话~

Samples
Input Copy
1 3 5
Output
Beautiful flowers!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
int a[1011][1011];
int main()
{
	int n,m,k;
	cin>>n>>m>>k;
	if((n+m==2)&&(k==1)||k>=2)
	cout<<"Beautiful flowers!"<<endl;
	else
	cout<<"Oh! My poor HJ!"<<endl;
   return 0;
}

因为本题说,一个位置和他上下左右四个方向位置的颜色不同,对于上下左右这四个位置,是可以相同的,所以可以知道当k>=2的时候任何情况都是满足情况的,但是需要特判一种情况就是当n1&&m1时,k=1也是满足的。

问题3: 川川教练的困惑

Description
在SMU算法竞赛团队中,谁的地位最高呢?答案是毋庸置疑的——大家发自内心爱戴的川川教练。川川教练对队内事务都非常上心,队员们的需求都尽量满足,队员们的问题也都尽快解决。但是最近川川总感觉力不从心,什么都要自己做实在是太累了!所以他需要你的帮助,这样他就可以有更多的时间和精力去和领导斗智斗勇,去为团队争取更多经费。最近,川川教练需要在新加入的集训队员中,挑选出一支最强的队伍去参加大学生程序设计竞赛。

川川之前太忙了,并不了解新的集训队员,只能根据HJ提供的队员能力值来筛选队员了。我们的大原则就是强强联手。具体的,新的集训队员一共n个人,HJ会为你提供每个人的编程能力值w。你需要找到编程能力值之和最大的**三个人****,输出他们的编程能力值之和。特别的,如果找不到一个队伍的编程能力值之和大于m,则输出"Waiver!"。

Input
第一行输入一个整数n,一个整数m,中间用空格隔开。
第二行输入n个整数wi代表编程能力值。
保证所有数据:
3≤n≤100
0≤m≤300
−100≤wi≤100
Output
如果任意组合,都无法使得队伍的英语能力值之和大于m,输出一行字符串:“Waiver!”(不含引号)

否则输出一个整数,表示在满足队伍英语能力值之和大于m的情况下能组成的最大编程能力值。

Samples
Input Copy
4 100
50 50 55 -5
Output
155
Hint

  1. 样例1说明
    我们选择前三个人,编程能力为155满足要求,同时也能获得最大的编程能力和。
  2. 样例2说明
    怎么选也满足不了要求,Waiver!
  3. 注意:编程能力可能为负数哦,这也是可以理解的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
int a[1011];
int cmp(int a,int b)
{
   return a>b;
}
int main()
{
	ll n,m,i,k;
	cin>>n>>m;
	for(i=0;i<n;i++)
	{
	   cin>>a[i];
	}
	sort(a,a+n,cmp);
	k=a[0]+a[1]+a[2];
	if(k>m)
	cout<<k<<endl;
	else
	cout<<"Waiver!"<<endl;
   return 0;
}

直接sort排序,输出前三个即可。

问题4:kth的自拍照

Description
kth特别喜欢自拍,但是她的手机被zyj摔在地上后,前置摄像头坏了,不管拍什么照片都是逆时针旋转了90°,而且照片都还是黑白的.这样的照片怎么能让kth找到对象呢?
现在kth向聪明的你求助,写一个程序帮助kth把图像旋转回来.(她手机太垃圾了,不带图片旋转功能).
因为照片是黑白的.所以对于手机屏幕来说,只有白色和黑色2种情况.
现在给你图片(通过01矩阵表示),对该图片进行旋转.使得图片显示正常.

Input
给你n∗n的矩阵且矩阵元素只有0和1,对矩阵实现旋转操作,使得图片恢复正常.
2≤n≤1000

Output
输出旋转之后的矩阵.矩阵每个元素间隔一个空格.

Samples
Input Copy
2
0 1
1 0
Output
1 0
0 1
Hint
考虑一下旋转的方向.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
int a[1011][1011];
int main()
{
	ll n,i,j;
	cin>>n;
	for(i=0;i<n;i++)
	{
	   for(j=0;j<n;j++)
	   {
	     cin>>a[i][j];
	   }
	}
	for(i=0;i<n;i++)
	{
	   for(j=n-1;j>=0;j--)
	   {
	      if(j==n-1)
	         cout<<a[j][i];
	      else
	         cout<<" "<<a[j][i];
	   }
	   putchar('\n');
	}
   return 0;
}

问题5:We are singers

Description
在简谱中,音符是记录音的高低和长短的符号。而用来表示这些音的高低的符号,是用七个阿拉伯数字作为标记,它们的写法是:1、2、3、4、5、6、7,读法为:do、re、mi、fa、sol、la、si。现在给你一段由N个音符构成的简谱,以及唱出来的读音(长度小于10的字符串)的记录,请你判断总共唱错了几个读音。

Input
第一行输入一个整数N( 0<N≤104 );
第二行包含N个数字构成的简谱,数字间用空格隔开;
第三行包含N个读音,读音间用空格隔开.

Output
总共唱错的读音个数.

Samples
Input Copy
8
1 2 3 4 5 6 7 1
do re mi fa sol la si der
Output
1

#pragma GCC optomize(2)
#pragma G++ optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=1e7+7;
int a[maxn];
map<int,string> p;
vector<int> q;
void init()
{
   p[1]="do",p[2]="re",p[3]="mi",p[4]="fa",p[5]="sol",p[6]="la",p[7]="si";
}

int main()
{
	init();
	int n,i,sum=0;
	string s;
	cin>>n;
	q.resize(n);
	for(i=0;i<n;i++)
	{
		cin>>q[i];
	}
    for(i=0;i<n;i++)
    {
       cin>>s;
       if(s==p[q[i]])
       continue;
       else
       sum++;
	}
	cout<<sum<<endl;
   return 0;
}

本题涉及stl相关知识点,目前正在studying

问题6:Incompetent Fury of a Single Dog

Description
SMU的英文全称是Southwest Minzu University,中文名叫做西南民族大学。这所大学因为男女比例约为2比8,因此又被大家戏称为稀男民族大学,又因为民族同学们,通常能歌善舞,且校内的舞蹈、唱歌活动非常之多,所以被戏称为稀男歌舞大学。
在计算机学院中,男同学的比例远高于其余学院,所以计算机学院的脱单率遥遥领先。但在计算机学院的算法竞赛团队中,却出现了诡异的一个现象:某一届的集训队员,竟然全都是SingleDog。他们非常讨厌被人私下嘲笑为SingleDog。最初,如果听到或者看到SingleDog这个字眼,他们就会失去理智,慢慢的,他们只要看到情侣出现,就抑制不住心中的愤怒。现在情况更加严重了!他们只要看到成双成对的东西,都会开始无能狂怒。现在有一份集训队的通知文件,必须要发到群里,为了让他们心平气和的看完这份文件,只能精简一些文字了。具体的精简策略:集训队的通知文件是一堆小写字母,为了使这些字母不要成双成对的出现,我们只保留每种字母出现的第一个就好。

Input
第一行输入一个n,代表集训队的通知文件的长度。
第二行输入一个字符串s,代表集训队的通知文件。
保证对于所有数据: 1≤n≤1000, 字符串s中,只包含a ~ z 的小写字母。

Output
第一行输出处理后的通知文件长度。

第二行输出处理后的集训队通知文件。

Samples
Input Copy
18
woyexiangtanlianai
Output
11
woyexiangtl

#pragma GCC optomize(2)
#pragma G++ optimize(2)
#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
const int N=1e9+7;
char a[1010];
char flag[1010];
int main()
{
   int i,j,sum=0,n;
   cin>>n;
   cin>>a;
   for(i=0;i<n;i++)
   {
      for(j=i+1;j<n;j++)
      {
        if(a[i]==a[j]){
        	flag[j]=1;
		}
	  }
   }
   for(i=0;i<n;i++)
   {
      if(flag[i]!=1)
      sum++;
   }
   cout<<sum<<endl;
   for(i=0;i<n;i++)
   {
      if(flag[i]!=1)
      cout<<a[i];
   }
   return 0;
}

就是将数组扫一遍,然后比较一下,用flag数组标记一下。

问题7:小胖的生日(birthday)

Description
小胖的生日是 YY 年 MM 月 DD 日,他想知道自己出生后第一万天纪念日的日期(出生日算第 0 天)。

Input
输入文件第一行分别读入 YY,MM,DD 其中 1949≤YY≤2002,日期绝对合法。

Output
输出文件只有一行,即小胖生日第一万天以后的日期,格式为 “YY-MM-DD”。

Samples
Input Copy
1975 7 15
Output
2002-11-30

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
   int y,m,d;
   scanf("%d %d %d",&y,&m,&d);
   int sum=1;
   int s[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};/利用数组存月份
   while(sum<=10000)
   {
     d++;
     if((y%4==0&&y%100!=0)||(y%400==0)){
     	s[2]=29;
	 }
	 else{
	 	s[2]=28;
	 }
	 if(d>s[m]){
	    m++;
	    d=1;
	 }
	 if(m>12)
	 {
	   y++;
	   m=1;
	 }
	 sum++;
   }
   printf("%d-%d-%d",y,m,d);
   return 0;
}

问题8:字符串展开

Description
小 H 在“超级巫师大战”中获得了冠军,宏校长一高兴,给了他进入魔法学院机密图书馆的权利,有一天,小H 在图书馆里找到了一本秘籍,上面写着“扩展魔法”,该魔法是一个字符串,两个数字之间的数用“-”省略,以尽量节省能量,并可以利用微量能量扩展开来。
比如:现在的魔法咒语是 ffdfd2-5,扩展后为 ffdfd2345。现在,小 H 想知道一个魔法咒语使用扩展魔法后,咒语会变成什么样子(注意: 如果减号右边的数字小于或等于左边数字,输出时,要保留中间的减号,例如:“3-1”应输出为“3-1”)

Input
一行字符串,仅由数字、小写字母和减号“-”组成。行首和行末均无空格(长度小于 256)

Output
只有一行,为展开后的字符串

Samples
Input Copy
abcs-w1234-9s
Output
abcs-w123456789s

#include<bits/stdc++.h>
using namespace std;
int main(){
	char str[300]={0};
    gets(str);
    char str2[300]={0};
    char tem1,tem2;
    int i,j,len1,k=0,m;//注意此处的m要定义在主函数内部,如果定义在主函数外部的话那就默认为0啦,定义在主函数内部为随机数
    len1=strlen(str);
    for(i=0;i<len1;i++)
    {
       if(str[i]>='0'&&str[i+1]=='-'&&str[i+2]<='9')
	   {
	      if(str[i]>=str[i+2]){
	      	str2[k]=str[i];
		    k++; 
		  }
		else
		{
		  tem1=str[i];
		  tem2=str[i+2];
		  m=i;
		  for(j=tem1;j<=tem2;j++)
		  {
		    str2[k]=j;
		    k++;
		  }
		}
	}
    else if(i==(m+1)||i==(m+2))
		{
		  continue;
		}
		else
		{
		  str2[k]=str[i];
		  k++;
	}
}
puts(str2);//puts只用来输出字符串char类型的,并且自带换行
	return 0;
}

问题9:懒羊羊找朋友

Description
最近电视上热播“喜羊羊与灰太狼”,大家都说“做人要做懒羊羊”,为什么呢?因为他不愿意多做一个动作、不愿意多动一个脑筋,甚至懒得张嘴吃饭,简直是懒的无与伦比!

话说羊村的羊还真多啊!每周一早晨,羊村老村长慢羊羊同志学着人类的学校,把所有羊列队在广场上进行思想教育,主要是保持警惕防止狼类的攻击,当然也包括对懒羊羊之类的“异类”进行批评教育。

羊群列队成一个m∗n的方阵,每只羊站在一个格子里,而且是长期固定的,便于点名啊:)晕倒!当然,这样一来的好处是,大家都知道自己的朋友站在哪个位置,虽然它们可能互相看不见,但心里都知道,并且在老村长进行无聊的训教时,大家都还想赶快结束赶快找离自己最近的朋友交流周末的开心事呢?

懒羊羊也想尽快找到自己的好朋友聊天,但是他既不愿意多走路、又不愿意动脑筋去想怎么走,所以就请智羊羊同学帮它编个程序,以便快速定位找到离它最近的一位好朋友。

如果你是智羊羊,你怎么完成这个任务呢?

Input
第1行为两个整数m和n,2≤m,n≤100。

第2行为懒羊羊的位置x,y,表示在第x行y列。

以下m行为一个m∗n的数字方阵,所有a[i,j]的值相等的表示是好朋友,1≤a[i,j]≤100。

每行的两个数之间都有一个空格分隔。

Output
输出一行两个数x1,y1,表示懒羊羊最近的一个朋友的位置在第x1行y1列,之间用一个空格隔开。

如果最近的的朋友不只一个,则输出x1最小的,如果还不唯一则输出y1最小的。

数据保证懒羊羊一定有朋友。

Samples
Input Copy
4 4
1 2
2 1 2 1
1 3 1 3
2 1 2 2
2 2 1 3
Output
1 4

#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
int a[200][200];
int main()
{
	int n,m,x,y,min=1000000,x1,y1;
	cin>>n>>m;
	cin>>x>>y;
	for(int i=1;i<=n;i++)
	{
	    for(int j=1;j<=m;j++)
	    {
	      cin>>a[i][j];
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
		   int cd=abs(i-x)+abs(j-y);
		   if(a[i][j]==a[x][y]&&cd!=0&&cd<min)
		   {
		     min=cd;
		     x1=i;
		     y1=j;
		   }
		}
	} cout<<x1<<" "<<y1<<'\n';
	 return 0;
}

问题10:数字配对

对于给定的一列数字,数字个数为偶数,你需要解决如下问题:将给定的数列中的数字两两配对,这样每一对数字的和将形成一个新数列,对于不同的配对方法,新数列中的最大值也不同,寻找一个好的配对方法,使得新数列中的最大值最小。

Input
第一行一个整数n(n≤10000)。 第二行有n个正整数,为给定的一列数字(数字均小于maxint div 2)。

Output
一个正整数,新数列中的最大值的最小值。

Samples
Input Copy
4
1 5 2 8
Output
9
Hint
1与8配对 2与5配对 结果为9。

#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
int s[10000],s1[10000];
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
	   cin>>s[i];
	}
	sort(s,s+n);
	for(int i=0;i<n;i++)
	{
	  s1[i]=s[i]+s[n-1-i]; 
	}
	sort(s1,s1+n);
	cout<<s1[n-1];
	 return 0;
}

问题11:弗雷德的困惑

Description
弗雷德先生想在路易斯安娜州买一块地造房子。

在调查中,他了解到由于密西西比河的侵蚀,路易斯安娜州正在以每年50平方英里的速度变小。因为弗雷德先生希望在他的新房子里生活直至终老,所以他想知道他的房子是否会被侵蚀掉。

经过进一步研究,弗雷德发现将要被侵蚀的陆地呈半圆形。半圆是一个以(0,0)点为中心的圆的一半,半圆的直边是X轴(如下图所示)。X轴以下的部分在水中。在第一年的开始,圆的面积是0。

Input
仅一行,为两个整数x,y(−109≤x≤109,0≤y≤109),表示房子的坐标。

Output
可以最多使用多少年。

注意:如在边界上,认为已经被侵蚀。

Samples
Input Copy
5 5
Output
1

#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
const double PI=acos(-1);
int read()
{
   int ans=0,sign=1;
   char ch=getchar();
   while(ch<'0'||ch>'9')
   {
     if(ch=='-')
     {
        sign=-1;
        ch=getchar();
	 }
   }
   while(ch>='0'&&ch<='9')
   {
    ans=(ans<<1)+(ans<<3)+(ch^48);
    ch=getchar();
   }
   return ans*sign;
}
void print(ll x)
{
	if(x<0)
	{
	  putchar('-');
	  x=-x;
	}
	if(x>9)
	print(x/10);
	putchar(x%10+'0');
}
int main()
{
	ll x,y,t=0;
	x=read();
	y=read();
	t=(x*x+y*y)*PI/2/50;
	cout<<t<<'\n';
	
	
   return 0;
}

求出半圆的面积,然后除以50即可。

问题12:监考老师

Description
在一个大试场里,有n行m列的考生,小王和众多同学正在考试,这时,有一部分考生作弊,当然,监考老师能发现他们。但是只有一个监考老师,他由于高度近视,只能发现与他同行同列的作弊者,而且由于监考老师年老体弱,在考试过程中无法移动。现在已知n*m个考生中谁在作弊,请帮监考老师找一个位置,可以发现最多的作弊者(监考老师可以和某个考生在同一位置)。如果监考老师的位置上的考生在作弊,那么监考老师先前后看,发现他作弊,再左右看,又发现他作弊,算做发现2个考生作弊。

Input
第一行两个数n,m ,表示试场是nm的,接下来是nm的矩阵,1表示作弊,0表示不作弊。

Output
共一行,一个数,表示最多可以发现多少作弊者。

Samples
Input Copy
5 5
0 0 1 0 0
0 0 1 0 0
1 1 1 1 1
0 0 1 0 0
0 0 1 0 0
Output
10
Hint
样例说明:监考老师在最中间,那个位置上的作弊者算作2次。

数据范围:

对于50 %的数据,0<n,m≤10
对于100 %的数据,0<n,m≤100,所有数据都在long int范围内

#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
ll a[200],b[200];
int main()
{
	ll n,m,c,shu=0;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
	   for(int j=0;j<m;j++)
	   {
	     cin>>c;
	     if(c==1)
	     {
	       a[i]++;/对应的行数加1
	       b[j]++;/对应的列数加1
		 }
	   }
	}
	for(int i=0;i<n;i++)
	{
	   for(int j=0;j<m;j++)
	   {
	      shu=max(shu,a[i]+b[j]);
	   }
	}
	cout<<shu<<'\n';
	return 0;
}

问题13:象棋比赛问题

(天梯赛选拔赛2)
Description
有N个人要参加国际象棋比赛,该比赛要进行K场对弈。每个人最多参加两场对弈,最少参加零场对弈。每个人都有一个与他人都不相同的等级(用一个正整数来表示)。
在对弈中,等级高的人必须用黑色的棋子,等级低的人必须用白色的棋子。 每个人最多只能用一次黑色的棋子和一次白色的棋子。
为了增加比赛的客观度,观众希望K场对弈中双方等级差的总和最小。比如有7个选手,他们的等级分别是30,17,26,41,19,38,18,要进行3场比赛,最好的安排是 2 vs 7, 7 vs 5,6 vs 4,此时等级差的总和为(18-17)+(19-18)+(41-38)=5 达到最小。

Input
第一行两个整数N、K。接下来N行,第i行表示第i−1个人等级。

Output
最小等级差的总和

Samples
Input Copy
7 3
30
17
26
41
19
38
18
Output
5
Hint
90%数据 N≤3000
100%的数据 N≤100000
所有等级值<108 1≤K≤N−1

#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
const double PI=acos(-1);
inline int read()
{
   int ans=0,sign=1;
   char ch=getchar();
   while(ch<'0'||ch>'9')
   {
     if(ch=='-')
     {
        sign=-1;
        ch=getchar();
	 }
   }
   while(ch>='0'&&ch<='9')
   {
    ans=(ans<<1)+(ans<<3)+(ch^48);
    ch=getchar();
   }
   return ans*sign;
}
void print(ll x)
{
	if(x<0)
	{
	  putchar('-');
	  x=-x;
	}
	if(x>9)
	print(x/10);
	putchar(x%10+'0');
}
int a[maxn],b[maxn];
int main()
{
	ll n,k,sum=0,ans=0;
	n=read();k=read();/快读
	for(int i=1;i<=n;i++)
	{
	   cin>>a[i];
	}
	sort(a+1,a+n+1);/从小到大排序
	for(int i=1;i<n;i++)
	{
		b[i]=a[i+1]-a[i];/用数组b来储存前一项减去后一项的差值
	}
	sort(b+1,b+n);/对n-1个差值进行排序,n个数两两相减有n-1个结果
	for(int i=1;i<=k;i++)/博弈k次
	{
	   sum+=b[i];
	}
	cout<<sum<<'\n';
   return 0;
}

问题14:购物

Description
你就要去购物了,现在你手上有N种不同面值的硬币,每种硬币有无限多个。为了方便购物,你希望带尽量少的硬币,但要能组合出1到X之间的任意值。

Input
第一行两个数X、N,以下N个数,表示每种硬币的面值。

Output
最少需要携带的硬币个数,如果无解输出-1.

Samples
Input Copy
20 4
1 2 5 10
Output
5
Hint
对于30%的数据,满足N≤3,X≤20;
对于100%的数据,满足N≤10,X≤1000.

#pragma GCC optimize(2)
#pragma G++ optimize(2)
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
const double PI=acos(-1);
inline int read()
{
   int ans=0,sign=1;
   char ch=getchar();
   while(ch<'0'||ch>'9')
   {
     if(ch=='-')
     {
        sign=-1;
        ch=getchar();
	 }
   }
   while(ch>='0'&&ch<='9')
   {
    ans=(ans<<1)+(ans<<3)+(ch^48);
    ch=getchar();
   }
   return ans*sign;
}
void print(ll x)
{
	if(x<0)
	{
	  putchar('-');
	  x=-x;
	}
	if(x>9)
	print(x/10);
	putchar(x%10+'0');
}
int a[2020];
int main()
{
	int x,n;
	x=read();n=read();
	for(int i=1;i<=n;i++)
	{
	 cin>>a[i];
	}
	sort(a+1,a+1+n);
	int sum=0,ans=0;
	if(a[1]!=1)/如果第一个不是1的话会无解,直接返回-1即可
	{
	  return -1;
	}
		while(x>sum)/只要累加的sum总和比题里给的x值小就继续此循环
	{
	  for(int i=n;i>=1;i--)/从大到小枚举,要求数量最小那就从最大的开始枚举,符合贪心的思想
	  {
	    if(a[i]<=sum+1)/记得sum要加1!!!
	    {
	       sum+=a[i];
	       ans++;
	       break;
		}	
	  }
	}
	cout<<ans<<'\n';
   return 0;
}

本题为贪心算法。

问题15:字符串按字典序从小到大输出

intput
3
abc
bac
cab

output
abc
bac
cab

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;

int main()
{
	int i,n,j;
	string str[1000],t;
	cin>>n;
	for(i=0;i<n;i++)
	{
		cin>>str[i];
	}
	for(i=0;i<n-1;i++)
	{
		for(j=0;j<n-1-i;j++)
		{
			if(str[j]>str[j+1])
			{
				t=str[j];
				str[j]=str[j+1];
				str[j+1]=t;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		cout<<str[i]<<'\n';
	}
   return 0;
}

char sr[] 输入一个字符,string str[] 输入一个字符串;
string a 相当于char a[];
string a[] 相当于char a[] [],但没有string[][]这种定义的

问题16:圆

Description
给出 N 个圆,保证任意两个圆都是相离的,然后给出两个点(x1,y1)、(x2,y2),保证均不在某个圆上,要从(x1,y1)到 (x2,y2)画条曲线,问这条曲线最少要穿过多少次圆的边界?

Input
第一行一个整数 N,表示圆的个数; 第二行 N 个整数,表示 N 个圆的 X 坐标; 第三行 N 个整数,表示 N 个圆的 Y 坐标; 第四行 N 个整数,表示 N 个圆的半径 R; 第五行四个整数 x1,y1,x2,y2。

Output
仅一个数,表示最少要穿过多少次圆的边界。

Samples
Input 复制
1
0
0
2
-5 1 5 1
Output
0
Input 复制
7

1 -3 2 5 -4 12 12
1 -1 2 5 5 1 1
8 1 2 1 1 1 2
-5 1 12 1
Output
3
Hint
1≤N≤50,坐标范围[-1000,1000],每个圆的半径 1≤R≤1000。 保证没有两个圆有公共点,起点和终点不会落在某个圆的边界上。

#include<bits/stdc++.h>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=1e5+9;
int x[60],y[60],r[60];
int read()
{
	int ans=0,sign=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')
		{
			sign=-1;
			ch=getchar();
		}
	}
	while(ch>='0'&&ch<='9')
	{
		ans=(ans<<1)+(ans<<3)+(ch^48);
		ch=getchar();
	}
	return ans*sign;
}
 
double dis(int x1,int y1,int x2,int y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));	
}
int main()
{
	int n,sum=0;
	int x1,y1,x2,y2;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
	  scanf("%d",&x[i]);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&y[i]);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&r[i]);
	}
	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
	
	for(int i=1;i<=n;i++)
	{
		if((dis(x1,y1,x[i],y[i])<r[i])^(dis(x2,y2,x[i],y[i])<r[i]))
		{
			sum++;
		}
	}
	 printf("%d",sum);
	return 0;
 } 

如果这两个点没有在任何一个园内,那么他们任意弯曲,一定可以不碰的任何一个圆,如果这两个点,都在一个圆内,那么,他们也碰不到任何一个圆,如果,一个点在一个圆内,一个在圆外,那么就碰到一次。

钻石

Description
贝西总是很喜欢闪闪发光的东西,在业余时间已经对钻石产生了兴趣!她收集了不同大小的N个钻石(N≤1000),她想把一些摆放在谷仓的陈列柜中。由于希望在这种情况下钻石的尺寸相对相似,所以她决定如果它们的尺寸差异不大于K,则这两颗钻石可以一起展示。给定K,请帮助贝西确定她可以显示的钻石的最大数量。

Input
第一行包含N和K(0≤K≤10,000)。
接下来N行每行一个整数表示钻石大小的整数。所有尺寸均为正数,不超过10,000,000。

Output
一行一个整数,贝西可以展示的最大钻石数量。

Samples
Input Copy
5 3
1
6
4
3
1
Output
4
Hint
【样例解释】1 4 3 1 放在一起数量最多。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	long long n,k,i,j,max=-1000,a[1001],c[1001];
	cin>>n>>k;
	for(i=0;i<n;i++)/因为数组c是储存两个数的差值的所以要初始成1
	{
	  c[i]=1;/这个for循环的意思是将c数组的所有值全部都初始成1.
	}
	for(i=0;i<n;i++){
		 cin>>a[i];
	}
	sort(a,a+n);
		for(i=0;i<n-1;i++)/两层for循环判断一个数组中两个数的差值的大小。
        for(j=i+1;j<n;j++){
        	if(a[j]-a[i]<=k)
        	c[i]++;
        else 
		break;
		}
	for(i=0;i<n;i++)
	if(max<c[i])
	max=c[i];  
	cout<<max;
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值