YF的“愉快”一周(第一周)

目录

一,循环和排序

A--sort

B---集合相减

C---A^B

二,枚举

A---Together

B---Fractions Again?!

C---Maximum Product

D---Number Box

E---Ants


一,循环和排序

A--sort

        给你n个整数,请按从大到小的顺序输出其中前m大的数。

Input

每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。

Output

对每组测试数据按从大到小的顺序输出前m大的数。

Sample

InputcopyOutputcopy
5 3 3 -35 92 213 -644 
213 92 3

难点:本题的数据较大,数组元素较多,如果使用冒泡,插入,选择这些排序会出现超时的问题,所以我们使用桶排序。

AC代码

#include<stdio.h>
const int N=1e6+5;
int a[N];//定义的一个数量级为1000005的数组

int main()
{
	int n,m;
	while(~scanf("%d%d",&n,&m)){
		for(int i=0;i<n;i++){
		int x;
		scanf("%d",&x);
		a[x+500000]++;//这里x的取值为-500000到500000,所以需要加500000是数组大于0 
	}
	
	//从大到小排序 
	for(int i=1000000;i>=0;i--){
		if(a[i]>0){ 
			printf("%d",i-500000);
			m--;
			if(m==0) {
				printf("\n");
				break;
			}
			else printf(" ");
		}
	} 
	}

	return 0;
} 

B---集合相减

Input

每组输入数据占1行,每行数据的开始是2个整数n(0<=n<=100)和m(0<=m<=100),分别表示集合A和集合B的元素个数,然后紧跟着n+m个元素,前面n个元素属于集合A,其余的属于集合B. 每个元素为不超出int范围的整数,元素之间有一个空格隔开.
如果n=0并且m=0表示输入的结束,不做处理。

Output

针对每组数据输出一行数据,表示A-B的结果,如果结果为空集合,则输出“NULL”,否则从小到大输出结果,为了简化问题,每个元素后面跟一个空格.

Sample

InputcopyOutputcopy
3 3 1 2 3 1 4 7
3 7 2 5 8 2 3 4 5 6 7 8
0 0 
2 3
NULL

难点:本题题意可能优点难理解,就是输出集合B中有而A中没有的元素,如果集合A中的元素集合B都有,则输出NULL

AC代码

#include<stdio.h>

int Complement(int a[100],int b[100],int c[100],int m,int n);//集合A-B 
void sort_arr(int c[100],int n);//从小到大排序输出

int main()
{
	int m,n,i,j,count=0;
	int len[100],c[100][100];
	while(scanf("%d%d",&m,&n)&&(m!=0||n!=0))
	{
		int a[100],b[100];
		for(i=0;i<m;i++) scanf("%d",&a[i]);
		for(i=0;i<n;i++) scanf("%d",&b[i]);
		len[count]=Complement(a,b,c[count],m,n);//创建一个新的集合,将集合B没有而A有的放进去,并返回长度 
		sort_arr(c[count],len[count]);
		count++;
	}
	for(i=0;i<count;i++)
	{
		if(len[i]==0) printf("NULL"); 
		for(j=0;j<len[i];j++)
		{
			printf("%d ",c[i][j]);
		}
		printf("\n");
	}
	return 0;
}

int Complement(int a[100],int b[100],int c[100],int m,int n)
{
	int i,j,count=0;
	for(i=0;i<m;i++)//1 2 3
	{
		int flag=1;
		for(j=0;j<n;j++)//1 4 7
		{
			if(a[i]==b[j]) 
			{
				flag=0;
				break;
			}
		}
		if(flag)
		{
			c[count]=a[i];
			count++;
		}
	}
	return count;
}

//冒泡排序 
void sort_arr(int c[100],int n)
{
	int i,j,t;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n-1-i;j++)
		{
			if(c[j]>c[j+1])
			{
				t=c[j];c[j]=c[j+1];c[j+1]=t;
			}
		}
	}
	return;
}

C---A^B

求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”

Input

输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。

Output

对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。

Sample

InputcopyOutputcopy
2 3
12 6
6789 10000
0 0 
8
984
1

难点:本题的开方的数字很大,且只需要求出A^B的最后三位表示的整数,不能使用pow()含函数,我们可以自己写一个开方,并将每次的结果%1000,使其永远保持三位数。

AC代码

#include<stdio.h>
#include<math.h>

int main()
{
	int a,b,i;
	int t[1000],count=0;
	while(scanf("%d%d",&a,&b)&&(a!=0||b!=0))
	{
		t[count]=1;
		while(b!=0)
		{
			t[count]=t[count]*a;
			t[count]=t[count]%1000;//每开一次方,就取余一次,始终保持三位数 
			b--;
		}
		count++;
	}
	for(i=0;i<count;i++) printf("%d\n",t[i]);
	return 0;
}

二,枚举

A---Together

You are given an integer sequence of length N, a1​,a2​,...,aN​.

For each 1≤i≤N, you have three choices: add 1 to ai​, subtract 1 from ai​ or do nothing.

After these operations, you select an integer X and count the number of i such thatai​=X.

Maximize this count by making optimal choices.

Constraints

  • 1≤≤N≤105
  • 0≤ai​<105(1≤i≤N)
  • ai​ is an integer.

Input

The input is given from Standard Input in the following format:

N

a1,a2,……aN

Output

Print the maximum possible number of i such that ai​=X.

Sample 1

InputcopyOutputcopy
7
3 1 4 1 5 9 2
4

For example, turn the sequence into 2,2,3,2,6,9,22,2,3,2,6,9,2 and select X=2 to obtain 4, the maximum possible count.

Sample 2

InputcopyOutputcopy
10
0 1 2 3 4 5 6 7 8 9
3

Sample 3

InputcopyOutputcopy
1
99999
1

题意:给出一组数列,每个元素有三种选择(加1,减1,不变),数列变换后统计相同元素的数量,求出数列变换后相同元素的最大数量

难点:这题如果用枚举的思想会非常简单,用数组的下标表示元素,对初始数组的每个元素进行这三个操作后,统计整数序列中每个整数出现的次数,最后输出max

AC代码

#include<stdio.h>
const int N=1e6+5;
int a[N]={0};
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		int x;
		scanf("%d",&x);
		a[x]++;a[x-1]++;a[x+1]++;//对初始数组的每个元素进行这三个操作后,统计整数序列中每个整数出现的次数
	}
	
	int max=0;
	for(int i=0;i<N;i++){
		if(a[i]>0){
			if(a[i]>max) max=a[i];
		}
	}
	printf("%d",max);
	return 0;
}

B---Fractions Again?!

题意: 输入一个数字num,给出等式1/num=1/x+1/y,并统计个数

难点:本题题目不难理解但却不容易下手,我们根据等式1/num=1/x+1/y,得出1/y=(x-num)/x*num 。最后得出y=x*num/(x-num),而x可以根据上面的sample得出范围[num+1,num*2],最后判断x和y是否为整数就行

AC代码

#include<stdio.h>
int main()
{
	int num;
	while(~scanf("%d",&num)){
		int count=0,a[10005];
		for(int x=num+1;x<=2*num;x++){
			double y=1.0*num*x/(x-num);//通过题目等式得出公式 
			if(y==(int)y) {//判断整数 
				a[count]=x;
				count++;
			}
		}
		printf("%d\n",count);
		for(int i=0;i<count;i++) printf("1/%d = 1/%d + 1/%d\n",num,num*a[i]/(a[i]-num),a[i]);//注意格式
	}
	return 0;
}

C---Maximum Product

Given a sequence of integers S = {S1, S2, . . . , Sn}, you should determine what is the value of the maximum positive product involving consecutive terms of S. If you cannot fifind a positive sequence, you should consider 0 as the value of the maximum product.

Input
Each test case starts with 1 N 18, the number of elements in a sequence. Each element S i is an integer such that 10 S i 10. Next line will have N integers, representing the value of each element in the sequence. There is a blank line after each test case. The input is terminated by end of fifile (EOF)
Output
For each test case you must print the message: ‘ Case # M : The maximum product is P . ’, where M is the number of the test case, starting from 1, and P is the value of the maximum product. After each test case you must print a blank line.
Sample Input
3
2 4 -3
5
2 5 -1 2 -1

Sample Output
Case #1: The maximum product is 8.
Case #2: The maximum product is 20.

题意:给出一组数列,求出连续元素相乘的最大值,当最大值为负数时,输出0.

难点:连续相乘选择非常多,我们要选择一种有效的排列手段,将数组的第一个元素作为起点,将第二的元素作为终点,计算起点和终点所有数的乘积,且每次计算后终点向后移动一位,起点不变。求出max

AC代码

#include<stdio.h>

long long maxium(int a[20],int n); //当十个数全是10时,用int会溢出 

int main()
{
	int n,count=0;
	while(~scanf("%d",&n)){
		int a[20];
		count++;
		for(int i=0;i<n;i++) scanf("%d",&a[i]);
		printf("Case #%d: The maximum product is %lld.\n\n",count,maxium(a,n)); 
	}
	return 0;
}

long long maxium(int a[20],int n)
{
	long long max=0;
	for(int i=0;i<n;i++){//起点 
		long long t=1;
		for(int j=i;j<n;j++){//终点 
			t*=a[j];
			if(t>max) max=t; //重点:记录每一段数的乘积并进行比较 
		}
	} 
	return max;
}

D---Number Box

你有一个正整数 N。

我们有一个由 N 行和 N 列组成的网格,其中第 i 行从顶部开始,第 j 列从左侧开始的方格上有一个数字 Ai,j。

假设这个网格的上边缘和下边缘相连,左边缘和右边缘也相连。换句话说,满足以下条件:

(1, i) 是 (N, i) 的上方,(N, i) 是 (1, i) 的下方。(i, N) 是 (i, 1) 的左边,(i, 1) 是 (i, N) 的右边Takahashi 首先要选择以下八个方向之一:上、下、左、右,以及四个对角线方向。然后,他会从任意一个方格开始,沿着所选择的方向重复移动 N-1 次。 (1 ≤ i ≤ N)

在这个过程中,Takahashi 访问了 N 个方格。找出他按照访问顺序从左到右排列在方格上的数字所能组成的最大整数。

Constraints

  • 1≤N≤10
  • 1≤  Ai,j  ​≤9
  • All values in input are integers.

Sample 1

InputcopyOutputcopy
4
1161
1119
7111
1811
9786

If Takahashi starts on the square at the 22-nd row from the top and 44-th column from the left and goes down and to the right, the integer obtained by arranging the digits written on the visited squares will be 97869786. It is impossible to make a value greater than 97869786, so the answer is 97869786.

Sample 2

InputcopyOutputcopy
10
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111

Note that the answer may not fit into a 32-bit integer.

题意:有一个矩阵,矩阵上的每个点有8个方向可以选择,朝一个方向走,遇到边界则进行循环,把每个点的同一都加起来,求max

难点:理不清题意,在边界时要进行循环

AC代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	int N;
	int a[10][10];
	scanf("%d", &N);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			scanf("%1d", &a[i][j]);
		}
	}

	int x[8] = { 1,1,0,-1,-1,-1,0,1 };
	int y[8] = { 0,1,1,1,0,-1,-1,-1 };
	long long max = 0;

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {//确定起点 
			for (int k = 0; k < 8; k++) {//确定方向 
				long long sum = 0;
				int xi = i, yi = j;
				for (int c = 0; c < N; c++) {
					sum = sum * 10 + a[xi][yi];
					xi = (xi + x[k] + N) % N;
					yi = (yi + y[k] + N) % N;
					//这里是 (xi + x[k] + N) % N而不是 (xi + x[k] ) % N,因为这里可以朝x的负方向移动,
					//如果是 (xi + x[k] ) % N,那么数组下标会出现负数情况 
				}
				if (sum > max) max = sum;
			}
		}
	}

	printf("%lld", max);
	return 0;
}

E---Ants

An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it immediatelly falls off it. When two ants meet they turn back and start walking in opposite directions. We know the original positions of ants on the pole, unfortunately, we do not know the directions in which the ants are walking. Your task is to compute the earliest and the latest possible times needed for all ants to fall off the pole.

Input

The first line of input contains one integer giving the number of cases that follow. The data for each case start with two integer numbers: the length of the pole (in cm) and n, the number of ants residing on the pole. These two numbers are followed by n integers giving the position of each ant on the pole as the distance measured from the left end of the pole, in no particular order. All input integers are not bigger than 1000000 and they are separated by whitespace.

Output

For each case of input, output two numbers separated by a single space. The first number is the earliest possible time when all ants fall off the pole (if the directions of their walks are chosen appropriately) and the second number is the latest possible such time.

Sample

InputcopyOutputcopy
2
10 3
2 6 7
214 7
11 12 7 13 176 23 191
4 8
38 207

题意:一定长度的木棍上有n只蚂蚁移动,当两只蚂蚁碰撞时各自朝着当前相反的方向走。求所有蚂蚁离开木棍的最长时间和最短时间。

难点:很大程度上会被题目绕进去,但实际上不管蚂蚁有没有碰撞,都是一只向左,一只向右,所以这里就不需要考虑蚂蚁是否碰撞。

AC代码

#define _CRT_SECURE_NO_WARNINGS
const int L = 1e6 + 5;
int ant[L];
#include<stdio.h>
int main()
{
	int N;
	scanf("%d", &N);
	for (int i = 0; i < N; i++) {
		int len, n;
		scanf("%d%d", &len, &n);
		int max = 0, min = 0;//max最接近端点,min最接近中点 
		double center = 1.0 * len / 2;
		for (int j = 0; j < n; j++)
		{
			scanf("%d", &ant[j]);
			int max1, min1;
			if (ant[j] > center) {
				max1 = ant[j];
				min1 = len - ant[j];
			}
			else {
				max1 = len - ant[j];
				min1 = ant[j];
			}
			if (max1 > max) max = max1;
			if (min1 > min) min = min1;
		}
		printf("%d %d\n", min, max);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值