码迷,mamicode.com
首页 > 其他好文 > 详细

团队训练(一)

时间:2020-03-28 18:25:07      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:bit   注意   asd   else   循环   标记   结束   正整数   测试数据   

团队训练(一) -- 枚举

总结:第三题和第八题稍微要动动脑子,其他题直接无脑暴力枚举就完事.

1.密码箱

题目:
小明的密码箱打不开了,小明的密码箱是传统的3位滚轮密码。小明完全不记得他的密码了,所以他从 000开始以升序开始尝试,他已经试到第abc位密码了,可是箱子还是没有打开,他希望你将之后所有可能尝试的密码输出,这样他就可以完全不去思考,让他波动密码盘更有效率
Input
(输入多组数据)每行输入一个整数n(0 < n < 1000);n没有前缀0。
Output
n之后所有可能尝试的密码;输出有前缀0的。

Sample Input
989

Sample Output
990
991
992
993
994
995
996
997
998
999

题解:遍历n + 1 到 999即可,时间复杂度O(n),坑点:要有前缀0输出,注意分界点010.
方法一:特判三种情况; 方法二:输出格式的控制.

AC:
方法一:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;

int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		for(int i = n + 1; i <= 999; i++)
		{
			if(i < 10)
				printf("00");
			if(10 <= i && i < 100)
				printf("0");
			printf("%d\n",i);
		}
	}
	return 0;
}

方法二:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;

int main()
{
    int n,i;
    while(~scanf("%d",&n))
    {
        for(i=n+1;i<=999;i++)
            printf("%.3d\n",i);
    }
    return 0;
}

2.大乐透

题目:
在小明曾经玩过的一种对号码的纸牌游戏(乐透)里,玩家必须从{1,2,……,49}中选择6个数。玩Lotto的一个流行策略是(虽然它并不增加你赢的机会):就是从这49个数中,选出k(k>6)个数组成一个子集S,然后只从S里拿出牌来玩几局游戏。例如,k=8,s={1,2,3,5,8,13,21,34},那么有28场可能的游戏:[1,2,3,5,8,13],[1,2,3,5,8,21],[1,2,3,5,8,34],[1,2,3,5,13,21],……,[3,5,8,13,21,24]。
读取数字k和一组数S,输出由S中的数组成的所有可能的游戏。
Input
输入数据有多组,每组一行,每行有多个整数,其中第一个整数为数字k,接下来有k个整数,即子集S。当k为0,输入结束。
Output
输出由S中的数组成的所有可能的游戏。每种游戏一行。

Sample Input
7 1 2 3 4 5 6 7
0

Sample Output
1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 6 7
1 2 3 5 6 7
1 2 4 5 6 7
1 3 4 5 6 7
2 3 4 5 6 7

题解:暴力遍历该序列的子集,不过观察一下题意只能按顺序挑子元素出来.

AC:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
int num[55];
int k;
int main()
{
	while(~scanf("%d",&k) && k)
	{
		for(int i = 1; i <= k; i++)
			scanf("%d",&num[i]);
		for(int a = 1; a <= k; a++)
		{
			for(int b = a + 1; b <= k; b++)
			{
				for(int c = b + 1; c <= k; c++)
				{
					for(int d = c + 1; d <= k; d++)
					{
						for(int e = d + 1; e <= k; e++)
						{
							for(int f = e + 1; f <= k; f++)
							{
								printf("%d %d %d %d %d %d\n",num[a], num[b], num[c], num[d], num[e], num[f]);
							}
						}
					}
				}	
			}	
		}
	}
	return 0;
} 

3.丑数

题目:
只有质数2,3,5,7这几个作为因子的数叫做,丑数,比如前20个丑数是(从小到大来说) 1,2,3,4,5,6,7,8,9,10,12,14,15,16,18,20,21,24和25.
Input
我们给你个n(1<=m<=5842)当输入n为0结束。
Output
输出第n个丑数。每个数一行。

Sample Input
1
2
3
4
11

Sample Output
1
2
3
4
12

题解:有一点像规律题,我们可以发现,丑数都是由一个丑数乘一个因子而得来的,不过我们需要将每一个丑数进行排好序,也就是先存好第一个丑数为1,接着1 * 2 = 2,1 * 3 = 3, 1 * 5 = 5, 1 * 7 = 7, 这时候我们要取出最小的丑数也就是2,而这个丑数是我们由1 * 2,乘因子为2而得来的,所以我们会t2+1(t2是指前t2个丑数乘过因子2,不包括t2),也就是说下一个乘因子2的丑数将会是2,此时会有1 * 3 = 3, 1 * 5 = 5, 1 * 7 = 7, 2 * 2 = 4,找出最小的丑数是3,此时t3+1(t3是指前t3个丑数乘过因子3,不包括t3),因为丑数3是由1乘因子3而得来的,接着会有2 * 2 = 4, 3 * 2 = 6,1 * 5 = 5, 1 * 7 = 7,找出最小丑数4,此时t2+1,依次类推。
坑点:这道题可以用分解因子的方法来判断是否是丑数,不过会跑差不多30s吧,直接就T掉.

AC:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const int num = 5850;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
int b[4] = {2, 3, 5, 7};
int a[num], n;
int main()
{
	int t2 = 1, t3 = 1, t5 = 1, t7 = 1; 
	a[1] = 1;
	int cnt = 1;
	while(cnt <= 5842)
	{
		a[++cnt] = min(min(2 * a[t2], 3 * a[t3]), min(5 * a[t5], 7 * a[t7]));
		if(a[cnt] == 2 * a[t2])
			t2++; 
		if(a[cnt] == 3 * a[t3])
			t3++;
		if(a[cnt] == 5 * a[t5])
			t5++;
		if(a[cnt] == 7 * a[t7])
			t7++; 
	}
	while(~scanf("%d",&n) && n)
	{
		printf("%d\n",a[n]);
	}
	return 0;
}

4.字符串统计

题目:

Description
对于给定的一个字符串,统计其中数字字符出现的次数。
Input
输入数据有多行,第一行是一个整数n,表示测试实例的个数,后面跟着n行,每行包括一个由字母和数字组成的字符串,字符串的长度小于等于100。
Output
对于每个测试实例,输出该串中数值的个数,每个输出占一行。

Sample Input
2
asdfasdf123123asdfasdf
asdf111111111asdfasdfasdf

Sample Output
6
9

题解:遍历字符串,判断字符是否属于‘0-9‘,再把数量加起来即可,时间复杂度O(n).

AC:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const int num = 5850;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
char str[105];
int main()
{
	int t;
	scanf("%d",&t);
	while(t --)
	{
		scanf("%s",str);
		int len = strlen(str), cnt = 0;
		for(int i = 0; i < len; i++)
		{
			if(str[i] >= ‘0‘ && str[i] <= ‘9‘)
				cnt ++;
		}
		printf("%d\n",cnt);
	}
	return 0;
}

5.二倍问题

题目:
Description

给定2到15个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍。比如给定1 4 3 2 9 7 18 22,得到的答案是3,因为2是1的两倍,4是2个两倍,18是9的两倍。

Input
输入包括n组测试数据。每组数据包括一行,给出2到15个两两不同且小于100的正整数。每一行最后一个数是0,表示这一行的结束后,这个数不属于那2到15个给定的正整数。

Output
对每组输入数据,输出一行,给出有多少个数对满足其中一个数是另一个数的两倍。

Sample Input
3
1 4 3 2 9 7 18 22 0
2 4 8 10 0
7 5 11 13 1 3 0

Sample Output
3
2
0

题解:判断第一个与第二个、第三个、第四个···第n个是否为两倍,再判断第二个与第三个、第四个···第n个是否为两倍,用两重循环即可解决,时间复杂度O(n^2).

AC:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const int num = 5850;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
int a[20];
int main()
{
	int t;
	scanf("%d",&t);
	while(t --)
	{
		memset(a,0,sizeof(a));
		int n, cnt = 0, ans = 0;
		while(~scanf("%d",&n) &&n)
		{
			a[++cnt] = n;
		}
		for(int i = 1; i <= cnt; i++)
		{
			for(int j = i + 1; j <= cnt; j++)
			{
				if(a[i] * 2 == a[j] || a[j] * 2 == a[i])
					ans ++;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

6.矩形

题目:
在测试超大规模集成电路时,对给定的一个设计,专家要检测元件是否相互遮盖。一个元件可视为一个矩形,假设每个矩形都是水平排列的(边与x轴或y轴平行),所以长方形由最小的和最大的x,y坐标表示。
编程计算完全被覆盖的矩形个数。
Input
输入有多组长方形实例。对每组长方形,第一个数字是长方形的数量,然后是长方形的最小和最大x,y坐标(最小x,最大x,最小y,最大y)。
Output
对每组输入数据,输出一行,是被完全覆盖的长方形数量。

Sample Input
3
100 101 100 101
0 3 0 101
20 40 10 400
4
10 20 10 20
10 20 10 20
10 20 10 20
10 20 10 20

Sample Output
0
4

题解:因为输入的坐标是最小x,最大x,最小y,最大y,所以我们可以直接判断x1min <= x2min 且 x1max >= x2max 且 y1min <= y2min 且 y1max >= y2max 是否成立,若成立且没被完全覆盖过,则进行标记该矩形已经被完全覆盖,然后数量加起来即可,时间复杂度O(n).

AC:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const int num = 5850;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
struct pos
{
	int x1, x2, y1, y2;
}a[maxn];
int vis[maxn];
int n;
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i = 1; i <= n; i++)
			scanf("%d%d%d%d",&a[i].x1,&a[i].x2,&a[i].y1,&a[i].y2);
		int cnt = 0;
		memset(vis,0,sizeof(vis));
		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= n; j++)
			{
				if(i == j) //除掉自己本身的比较. 
					continue;
				if(a[i].x1 <= a[j].x1 && a[i].x2 >= a[j].x2 && a[i].y1 <= a[j].y1 && a[i].y2 >= a[j].y2 && !vis[j])
				{
					cnt++;
					vis[j] = 1;
				}
			}
		}
		printf("%d\n",cnt);
	}
	return 0;
}


7.抽奖

题目:
公司举办年会,为了活跃气氛,设置了摇奖环节。参加聚会的每位员工都有一张带有号码的抽奖券。现在,主持人依次公布 n 个不同的获奖号码,小谢看着自己抽奖券上的号码 num,无比紧张。请编写一个程序,如果小谢获奖了,请输出他中的是第几个号码;如果没有中奖,请输出 0。

Input
第一行一个正整数 n,表示有 n 个获奖号码,2<n≤100。
第二行包含 n 个正整数,之间用一个空格隔开,表示依次公布的 n 个获奖号码。
第三行一个正整数 num,表示小谢抽奖券上的号码。
1≤获奖号码,num<10000。

Output
一行一个整数,如果小谢中奖了,表示中奖的是第几个号码;如果没有中奖,则为 0。

Sample Input
7
17 2 3 4 9555 6 1
3

Sample Output
3

题解:用一个一维数组把获奖号码存起来,然后遍历一次号码,判断是否存在奖券上的号码,时间复杂度:O(n).

AC:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
int a[105];
int main()
{
	int n, num;
	scanf("%d",&n);
	for(int i = 1; i <= n ; i++)
		scanf("%d",&a[i]);
	scanf("%d",&num);
	int flag = 0, ans = 0;
	for(int i = 1; i <= n; i++)
	{
		if(num == a[i])
		{
			ans = i;
			flag = 1;
			break;
		}
	}
	if(flag)
		printf("%d",ans);
	else
		printf("0");
	return 0;
}


8.奶牛碑文

题目:
小伟暑假期间到大草原旅游,在一块石头上发现了一些有趣的碑文。碑文似乎是一个神秘古老的语言,只包括三个大写字母 C、O 和 W。尽管小伟看不懂,但是令他高兴的是,C、O、W的顺序形式构成了一句他最喜欢的奶牛单词“COW”。现在,他想知道有多少次 COW 出现在文本中。
如果 COW 内穿插了其他字符,只要 COW 字符出现在正确的顺序,小伟也不介意。甚至,他也不介意出现不同的 COW 共享一些字母。例如,CWOW 出现了 1 次 COW,CCOW 算出现了2 次 COW,CCOOWW 算出现了 8 次 COW。
Input
第 1 行为 1 个整数 N。
第 2 行为 N 个字符的字符串,每个字符是一个 C、O 或 W。
Output
输出 COW 作为输入字符串的字串出现的次数(不一定是连续的)。
提示:答案会很大,建议用 64 位整数(long long)。

Sample Input
6
COOWWW

Sample Output
6

备注:
对于 50% 的数据满足:N≤60。
对于 100% 的数据满足:N≤100000。
单组输入

题解:方法一:以每个‘O‘为一个分界点,把每个‘O‘左边的字符‘C‘的数量进行相加再与其右边字符‘W‘相加后的数量相乘即可,不过这里不能同时计算‘C‘与‘W‘的数量,复杂度会达O(n^2),会T,可能可以达到O(logn * n),不过我暂时没想出来,但可以分步进行计算,时间复杂度:O(3 * n)。
方法二:分别记录C,CO,COW的个数,因为CO的个数会是C的个数累加,COW的个数会是CO的个数累加,比如CCOOW,CO的个数就是2 + 2 = 4,也就是C的个数累加,因为‘O‘有两个所以累加两次,然后COW的个数就是4,因为W只有一个,只用累加CO的个数一次.

AC:
方法一:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 7;
const int maxm = 2e5 + 7;
const int num = 5850;
const long long inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
LL ans = 0;
int len;
char str[maxn];
struct ss
{
	int c, w;
}a[maxn];
int main()
{
	scanf("%d%s",&len,str);
	int cnt = 0, flag = 0; //cnt:‘O‘个数, flag:‘O‘左边‘C‘的个数 
	for(int i = 0; i < len; i++)
	{
		if(str[i] == ‘C‘)
			flag ++;
		if(str[i] == ‘O‘)
			a[++cnt].c = flag;
	} 
	flag = 0; // ‘O‘右边‘W‘的个数 
	for(int i = len, j = cnt; j > 0 && i >= 0; i --)
	{
		if(str[i] == ‘W‘)
			flag ++;
		if(str[i] == ‘O‘)
			a[j--].w = flag;		
	}
	for(int i = 1; i <= cnt; i++)
		ans += a[i].c * a[i].w; //当前‘O‘左边‘C‘的个数 * 右边‘W‘的个数 
	printf("%lld",ans);
	return 0;
} // 复杂度O(3*n)


方法二:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n,i;
    char ch1;
    while(cin >> n)
    {
        getchar();
        long long x1,x2,x3;//分别记录C,CO,COW的个数
        x1=x2=x3=0;
        for(i=1;i<=n;i++)
        {
            cin >> ch1;
            if(ch1==‘C‘)
                x1++;
            if(ch1==‘O‘)
                x2+=x1;
            if(ch1==‘W‘)
                x3+=x2;
        }
        cout << x3 << endl;
    }
    return 0;
}

团队训练(一)

标签:bit   注意   asd   else   循环   标记   结束   正整数   测试数据   

原文地址:https://www.cnblogs.com/K2MnO4/p/12588119.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!