枚举算法练习

A - Together

 

Problem Statement

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

For each 1≤�≤�1≤i≤N, you have three choices: add 11 to ��ai​, subtract 11 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≤�≤1051≤N≤105
  • 0≤��<105(1≤�≤�)0≤ai​<105(1≤i≤N)
  • ��ai​ is an integer.

Input

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

�N
�1a1​ �2a2​ .. ��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 �=2X=2 to obtain 44, 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个数,可以对每一个数做三种操作a,a+1,a-1,求所以操作完成后出现次数最多的数的个数。

分析:对于每个数枚举三种操作后的值,记录其出现次数,最后遍历求出现次数的最大值。

#include <stdio.h>
const int N=500000;
int b[N];
int main()
{
	int n,i,j,m;
	scanf("%d",&n);
	for(i=0 ; i<n ; i++){
		scanf("%d",&m);
			b[m]++;
			b[m-1]++;
			b[m+1]++;
	}
	int max=b[0];
	for(i=0 ; i<500000 ; i++){
		if(b[i]>max){
			max=b[i];
		}
	}
	printf("%d",max);
	return 0;
}

B - Fractions Again?!

 

Fractions Again?!
It is easy to see that for every fraction in the form 1k

(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.

输入

2
12
输出

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,记录所有满足的结果。

#include<bits/stdc++.h>
using namespace std;
int x[1100];
int y[1100];
int main()
{
    int n;
 
    while(~scanf("%d", &n))
    {
      int cc = 0;
      for(int i = 1 + n; i <= 2 * n; i++)
      {
         if(n * i % ( i - n) == 0)
         {
             x[cc] = n * i/( i - n);
             y[cc++]  = i;
         }
      }
      printf("%d\n",cc);
      //printf("%d\n",cc);
      for(int i = 0; i < cc; i++)
        printf("1/%d = 1/%d + 1/%d\n",n,x[i],y[i]);
    }
}

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.
题意:对于每一组给出的数据,求其连续子序列乘积的最大值

分析:暴力枚举所有起点和终点,用x记录积累乘积,比较所有乘积,返回最大值

#include <stdio.h>
int main()
{
	long long int n,c=0,i,m,a[20],j,s;
	while(~scanf("%lld",&n)){
		long long int max=0;
		c++;
		for(i=0 ; i<n ; i++){
			scanf("%lld",&a[i]);
		}
		for(i=0 ; i<n ; i++){
			s=1;
			for(j=i ; j<n ; j++){
				s=a[j]*s;
				if(s>max){
					max=s;
				}
			}
		}
			printf("Case #%lld: The maximum product is %lld.\n\n",c,max);
	}	
	return 0;
}

D - Division

枚举算法练习 - Virtual Judge (vjudge.net)

题意:给出一个数n,输出所有满足格式abde/fghij=n的式子

分析:枚举所有fghij的可能值,最小为01234,最大为6位数,判断n*fghij和fghij能否满足格式,格式:分子和分母中出现0~9的每个数。

#include <stdio.h>
int nn(int a,int b){
	int num[10]={0},i,l=0;
		for(i=0 ; i<5 ; i++){
			num[a%10]++;
			num[b%10]++;
			a/=10;
			b/=10;	
		}
	for(i=0 ; i<10 ; i++){
		if(num[i]>1){
			l=1;
		}
	}
		if(l==1)
			return 0;
		else
			return 1;
}
int main()
{
	int i,y,x,n,v=1;
	while(~scanf("%d",&n)){
		if(n==0){
			break;
		}
		if(v==0)
		printf("\n");
		v=0;
		int f=0;
		for(i=1234 ; i<=100000 ; i++){
			if(nn(i,i*n)){
					if(i*n<100000){
						printf("%05d / %05d = %d\n",i*n,i,n);
						f=1;
					}		
			}
			
		}
		if(f==0){
			printf("There are no solutions for %d.\n",n);
		}
		
	}
	return 0;
}

E - Number Box

枚举算法练习 - Virtual Judge (vjudge.net)

题意:给出矩阵,求其每个方向上的数连接后的最大值

分析:通过枚举所有起点,从起点出发各个方向,连接所访问的值,比较获得最大值

#include <stdio.h>

int main()
{
	int a[10][10]={0},N,i,j,k,m,shu;
	int dx[8] = { 1,1,0,-1,-1,-1,0,1 };
	int dy[8] = { 0,1,1,1,0,-1,-1,-1 };
	scanf("%d",&N);
	for(i=0 ; i<N ; i++){
		for(j=0 ; j<N ; j++){
			scanf("%1d",&a[i][j]);
		}
	}
	long long int max=-1;
	for(i=0 ; i<N ; i++){
		for(j=0 ; j<N ; j++){
			for(k=0 ; k<8 ; k++){
				long long int shu=0;
				int x=i,y=j;
				for(m=0 ; m<N ; m++){
					shu=shu*10+a[x][y];
					x=(x+dx[k]+N)%N;
					y=(y+dy[k]+N)%N;
				}
				if(max<shu){
					max=shu;
				}
			}
		}
	}
	printf("%lld",max);
	return 0;
}

F - 1D Pawn

枚举算法练习 - Virtual Judge (vjudge.net)

题意:给出N个方块,K个小球的初始位置,位于哪个方块上,Q次操作,每次操作移动当前小球到右侧相邻位置,若该位置有小球,则不移动,若当前位置在最右,不移动

分析:简单理解为若小球能往右移动,就移动位置。利用check标记当前位置是否被占用

#include <stdio.h>
int main(int argc, char *argv[])
{
	int N,K,Q,a[205]={0},i,b[205]={0},n;
	scanf("%d%d%d",&N,&K,&Q);
	for(i=0 ; i<K ; i++){
		scanf("%d",&a[i+1]);
		b[a[i+1]]=1;
	}
	for(i=0 ; i<Q ; i++){
		scanf("%d",&n);
		if(a[n]<N&&b[a[n]+1]==0){
			b[a[n]]=0;	
			a[n]=a[n]+1;
			b[a[n]]=1;
		}
	}
	printf("%d",a[1]);
	for(i=2 ; i<=K ; i++){
			printf(" %d",a[i]);
		}
	return 0;
}

G - Ants

枚举算法练习 - Virtual Judge (vjudge.net)

分析:最快时间就是蚂蚁的初始位置到边界的距离的最小值;最慢时间为当前位置到边界的最大值

#include<iostream>
using namespace std;
const int maxn = 1e+6 + 5;
int pos[maxn];
int t, n;
int L;
int mx, mi;
void solve() {
	for (int i = 1; i <= n; i++) {
		mx = max(mx, max(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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值