枚举算法练习

目录

A-Together

B-Fraction Again?!

C-maximum Product

D-Division

E-Number box

F- 1D Pawn

G-Ants


A-Together

Problem Statement

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 that ai​=X.

Maximize this count by making optimal choices.

Constraints

  • 1≤N≤10^5
  • 0≤ai​<10^5(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,2and 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

题目大意 

输入N,a1....ai....aN,每个ai可以选择三种处理方式,+1,-1,+0, 输出经过操作后数组中存在的个数最多的那个数

思路

对每个数都进行三次处理,找出处理后数组中个数最多的数 

代码 

#include<iostream>
using namespace std;
const int N=1e5+5;
int a[N];  //数组较大,提前定义
int main(){
int n;
scanf("%d",&n);
int ai;
while(n--){
	scanf("%d",&ai); 
	a[ai]++;   
	a[ai-1]++;
	a[ai+1]++;  //记录每种情况
}
int max=0;
for(int i=0;i<N-1;i++){
if(max<a[i])
	max=a[i];  //找出
}
cout<<max<<endl;
 
return 0;
 
} 

B-Fraction Again?!

It is easy to see that for every fraction in the form 1 k (k > 0), we can always find two positive integers x and y, x ≥ y, such that:

                                               1/ k = 1 /x + 1/ y

Now our question is: can you write a program that counts how many such pairs of x and y there are for any given k?

Input

Input contains no more than 100 lines, each giving a value of k (0 < k ≤ 10000).

Output

For each k, output the number of corresponding (x, y) pairs, followed by a sorted list of the values of x and y, as shown in the sample output.

Sample Input

2 12

Sample Output

2

1/2 = 1/6 + 1/3

1/2 = 1/4 + 1/4

8

1/12 = 1/156 + 1/13

1/12 = 1/84 + 1/14

1/12 = 1/60 + 1/15

1/12 = 1/48 + 1/16

1/12 = 1/36 + 1/18

1/12 = 1/30 + 1/20

1/12 = 1/28 + 1/21

1/12 = 1/24 + 1/24 

题目大意 

多组输入,每组有一个k,输出满足1/k=1/x+1/y的 x y 

 思路

1/k=1/x+1/y变式得 x =(y*x)/(y-k) ,而y的范围一定(k+1<=y<=2*k),因此写一个y范围的循环,其中满足条件x =(y*x)/(y-k)便输出

 代码

#include<cstdio>
int main()
{
	int k,z,x,y,a[10005],b[10005];
	while(~scanf("%d",&k)){
	      z=0;
	      for(y=k+1;y<=2*k;y++){  //y可取的范围
            if((y*k)%(y-k)==0){ 
                x=(y*k)/(y-k);  //满足条件
                if(x>=y){
                    a[z]=x; b[z]=y; z++;  //记录
                 }
             }
          }
	      printf("%d\n",z);  //满足条件的个数
     	  for(int i=0;i<z;i++){
		   	  printf("1/%d = 1/%d + 1/%d\n",k,a[i],b[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 find 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 Si is an integer such that −10 ≤ Si ≤ 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 file (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. 

题目大意 

 多组输入,每组输入N,s1...si...sN,输出最大的乘积

思路 

枚举所有乘积,记录最大值 

代码 

#include<cstdio>
int main()
{
	int n;
	int num=0;
	int si[25];
	long long p,zd;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++)
		{
			scanf("%d",&si[i]);
		}
		zd=0;
		  for(int i=0;i<n;i++) //枚举起点
        {
        	p=1;
            for(int j=i;j<n;j++) //枚举终点
            {
                p*=si[j];
                if(p>zd)
                    zd=p;  //保存最大值
            }
        }

	    num++;  
		printf("Case #%d: The maximum product is ",num);
		if(zd<0){
			printf("0.\n\n");
		}
		else{
			printf("%lld.\n\n",zd);
		} 
	}
	return 0;
}

 

D-Division

Write a program that finds and displays all pairs of 5-digit numbers that between them use the digits 0 through 9 once each, such that the first number divided by the second is equal to an integer N, where 2 ≤ N ≤ 79. That is, 

                                                       a b c d e / f g h i j = N

where each letter represents a different digit. The first digit of one of the numerals is allowed to be zero.

Input

Each line of the input file consists of a valid integer N. An input of zero is to terminate the program.

Output

Your program have to display ALL qualifying pairs of numerals, sorted by increasing numerator (and, of course, denominator). Your output should be in the following general form: xxxxx / xxxxx = N xxxxx / xxxxx = N . . In case there are no pairs of numerals satisfying the condition, you must write ‘There are no solutions for N.’. Separate the output for two different values of N by a blank line.

Sample Input

61

62

0

Sample Output

There are no solutions for 61.

79546 / 01283 = 62

94736 / 01528 = 62

题目大意

 给定N,用能否找出abcde 及 fghijk ,每个字母代表0~9的一个数字,且每数字只出现一次,使 a b c d e / f g h i j = N 成立

思路 

a b c d e / f g h i j = N 变式为a b c d e = N * f g h i j 。每个z字母位置出现的数字范围都是0~9,且数字只用一次,所以 01234为最小,五位数不超过10000,所以10000 / N为最大。

即搜寻 0 1 2 3 4—— 1 0 0 0 0 / N,判断每个数字只出现一次。

代码 

#include<iostream>
using namespace std;
int judge(int a, int b) {
    int num[10] = { 0 };
    for (int i = 0; i < 5; i++) {
    num[a % 10]++;
    num[b % 10]++;
    a /= 10;
    b /= 10;
    }
    for (int i = 0; i < 10; i++)if (num[i] > 1)return 0;
    return 1;
} //判断0~9每数字只出现一次
int main() {
    int n;
    bool f = false;
    while (cin >> n && n) {
         if (f){
    	    printf("\n"); //结尾空行
	     }
         else f = true;
         int flag = 0;
         for (int i=1234;i<=100000/n;i++) { //搜寻
             if (judge(i,i*n)) {  
                 printf("%05d / %05d = %d\n", i * n, i, n); //输出五位数(记得补零)
                 flag++;
                }
            }
        if (!flag)
	       printf("There are no solutions for %d.\n", n);//无解
     }
    return 0; 
}

 

E-Number box

 

Problem Statement

You are given a positive integer N.

We have a grid with N rows and N columns, where the square at the i-th row from the top and j-th column from the left has a digit Ai,j​ written on it.

Assume that the upper and lower edges of this grid are connected, as well as the left and right edges. In other words, all of the following holds.

  • (N,i) is just above (1,i), and (1,i) is just below(N,i). (1≤i≤N).
  • (i,N) is just to the left of (i,1), and (i,1) is just to the right of (i,N). (1≤i≤N).

Takahashi will first choose one of the following eight directions: up, down, left, right, and the four diagonal directions. Then, he will start on a square of his choice and repeat moving one square in the chosen direction N−1 times.

In this process, Takahashi visits N squares. Find the greatest possible value of the integer that is obtained by arranging the digits written on the squares visited by Takahashi from left to right in the order visited by him.

Constraints

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

Input

Input is given from Standard Input in the following format:

N
A1,1​ A1,2 ​… A1,N​
A2,1​ A2,2 ​… A2,N​
⋮⋮
AN,1 ​AN,2 ​… AN,N​

Output

Print the answer.

Sample 1

InputcopyOutputcopy
4
1161
1119
7111
1811
9786

If Takahashi starts on the square at the 2-nd row from the top and 4-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 9786. It is impossible to make a value greater than 9786, so the answer is 9786.

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.

题目大意 

输入N,及N行N列的矩阵, 可以从任意N( i , j )开始,可以选择8个方向,往上下左右或对角线走,走N-1次,求这N个数连接后的最大值。特别说明,N(i,N)往右走到N (i,1),N(1,j)往s上走到N (N,j),以此类推...

思路 

 暴力枚举所有走法,记录所连接数最大值

代码 

#include<iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int a[10][10]={0};
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			scanf("%1d",&a[i][j]); //输入矩阵
		}
			
	}	
	long long max=-1;
	int dx[8]={1,1,0,-1,-1,-1,0,1};
    int dy[8]={0,1,1,1,0,-1,-1,-1}; //8个方向
    for(int i=0;i<n;i++){  
		for(int j=0;j<n;j++){
			for(int k=0;k<8;k++){ //8种走法
				long long ans=0;
				int x=i,y=j; 
		        for(int l=0;l<n;l++){ //
		        	ans=ans*10+a[x][y];  //连接走过的数
		        	x=(x+dx[k]+n)%n;
                    y=(y+dy[k]+n)%n;  //当前位置
                }
                max=max>ans?max:ans; //记录最大值
            }
        }
    }
	printf("%lld",max);	
	return 0;

}

 

F- 1D Pawn

Problem Statement

There are N squares, indexed Square 1, Square 2, …, Square N, arranged in a row from left to right.
Also, there are K pieces. The i-th piece from the left is initially placed on Square Ai​.
Now, we will perform Q operations against them. The i-th operation is as follows:

  • If the Li​-th piece from the left is on its rightmost square, do nothing.
  • Otherwise, move the Li​-th piece from the left one square right if there is no piece on the next square on the right; if there is, do nothing.

Print the index of the square on which the i-th piece from the left is after the Q operations have ended, for each i=1,2,…,K.

Constraints

  • 1≤K≤N≤200
  • 1≤A1​<A2​<⋯<AK​≤N
  • 1≤Q≤1000
  • 1≤Li​≤K
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K Q
1A1​ 2A2​ …… AK​
1L1​ 2L2​ …… LQ​

Output

Print K integers in one line, with spaces in between. The i-th of them should be the index of the square on which the i-th piece from the left is after the Q operations have ended.

Sample 1

InputcopyOutputcopy
5 3 5
1 3 4
3 3 1 1 2
2 4 5

At first, the pieces are on Squares 1, 3, and 4. The operations are performed against them as follows:

  • The 3-rd piece from the left is on Square 4. This is not the rightmost square, and the next square on the right does not contain a piece, so move the 3-rd piece from the left to Square 5. Now, the pieces are on Squares 1, 3, and 5.
  • The 3-rd piece from the left is on Square 5. This is the rightmost square, so do nothing. The pieces are still on Squares 1, 3, and 5.
  • The 1-st piece from the left is on Square 1. This is not the rightmost square, and the next square on the right does not contain a piece, so move the 1-st piece from the left to Square 2. Now, the pieces are on Squares 2, 3, and 5.
  • The 1-st piece from the left is on Square 2. This is not the rightmost square, but the next square on the right (Square 33) contains a piece, so do nothing. The pieces are still on Squares 2, 3, and 5.
  • The 2-nd piece from the left is on Square 3. This is not the rightmost square, and the next square on the right does not contain a piece, so move the 2-nd piece from the left to Square 4; Now, the pieces are still on Squares 2, 4, and 5.

Thus, after the Q operations have ended, the pieces are on Squares 2, 4, and 5, so 2, 4, and 5 should be printed in this order, with spaces in between.

Sample 2

InputcopyOutputcopy
2 2 2
1 2
1 2
1 2

Sample 3

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

题目大意 

 由N 个方块,K件东西放在第Ai个方块上,操作Q次,如果Li前无东西且i不为N,将其移动至Li+1个方块上,输出最终物品在哪些方块上

思路 

标记有物品的方块,进行操作时根据条件改变标志,最终输出带标志方块位置

代码 

#include<iostream>
using namespace std;
int main() {
    int N, K, Q;
    int b[201] = { 0 };
    int a[201] = { 0 };
    scanf("%d %d %d", &N, &K, &Q);
    for (int i = 0; i < K; i++) {
	     scanf("%d", &a[i + 1]); 
		 b[a[i + 1]] = 1;   //标记
		}
    for (int i = 0; i < Q; i++) {
        int l;
        scanf("%d", &l);  //需判断是否移动的位置
        int p = a[l] + 1;  //右边位置
        if (!b[p] && a[l] != N) { 
            b[a[l]] = 0;  //删除原标记
            a[l] = a[l] + 1;  //往右移动
            b[a[l]] = 1;  //设置新标记
        }
    }
    for (int i = 1; i <= K - 1; i++)
	     printf("%d ", a[i]);
    printf("%d", a[K]);
    return 0;
}

 

G-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

题目大意 

在长度l的绳上有n只蚂蚁,分别在不同位置,每蚂蚁速度相同方向可选择向左向右,若相遇则掉头,求所有蚂蚁离开绳子的最短及最长时间

思路 

记录每只蚂蚁离开绳子的最长最短时间,标记(可以忽略掉头条件,当作每只蚂蚁走到底)

代码 

#include<iostream>
using namespace std;
const int maxn = 1e+6 + 5;
int pos[maxn],t, n,L,mx, mi;
void solve() {
    for (int i = 1; i <= n; i++) {
    mx = max(mx, max(pos[i], L - pos[i]));//最慢 //pos[i]往左走,L - pos[i]往右走
    mi = max(mi, min(pos[i], L - pos[i]));//最快
    }
}
int main() {
    cin >> t;
    while (t--) {
    cin >> L >> n;
    for (int i = 1; i <= n; i++)
    cin >> pos[i];
    mx = 0, mi = 0;
    solve();
    cout << mi << " " << mx << "\n";
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值