团队训练
Posted k2mno4
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了团队训练相关的知识,希望对你有一定的参考价值。
团队训练(一) -- 枚举
总结:第三题和第八题稍微要动动脑子,其他题直接无脑暴力枚举就完事.
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
",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
",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
",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
",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
",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
",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
",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;
}
以上是关于团队训练的主要内容,如果未能解决你的问题,请参考以下文章
清华&BAAI唐杰团队提出第一个开源的通用大规模预训练文本到视频生成模型CogVideo,含94亿超大参数量!代码即将开源!...