2020 Summer Team Contest
2020/08/20
最近时间紧张,上次组队赛还没总结,今天补上。
八月二十号也就是大前天,我的状态不太好,思路很乱,A了一道水题,老孔说A个题他好像以前做过,他直接把A题给AC了,老燕状态不错,自己A了三道题,我和老孔一起看C题,我想了思路,他写了代码,把C题也给A了,我又想了一会J题,是一个二分图匹配的题,但是没A成(匈牙利算法给忘了),最后我们队一共A了5道题,中游水平。
题目
H.Non-random numbers
水题一枚。
题意:给定一个n,问你满足条件的n位数有多少个。
条件就是一个数字位置不能是0,然后第i位上的数字不能是i。
思路:首先就是第一位只有8种情况,然后2-9位都有9种情况,再往后都是有10种情况。这里还有一个小技巧:就是1<n<100,long long int的数据大小不够使,我们可以把(*10)转化成(输出一个0)。
AC代码:
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int n;
scanf("%d",&n);
if(n<10)
{
long long int sum=8;
for(int i=1; i<n; i++)
sum*=9;
printf("%lld\n",sum);
}
else
{
long long int sum=8;
for(int i=1; i<9; i++)
sum*=9;
printf("%lld",sum);
for(int i=10; i<=n; i++)
printf("0");
}
return 0;
}
C.Desktop
题意:往给定大小的矩形桌面放大小为2×2的图标,图标可以重叠,但必须有一半大小(即1×2大小)露在外面才算有效,问最多能有效多少图标,输出这些图标的位置。
思路:这里提供一种解题思路(可能答案不唯一)如图图中标0的格是被浪费的格子,图层的方式就是将每两行按照两两相叠的方式涂好(如果有奇数就先将最后一行两两涂好)然后把图卡旋转90度按照之前的方式涂最后两行(因为这样涂最后只会浪费两个格子,而之前的图法至少会浪费两个格子)。这种涂法最后能放的图标总量就是n×m/2-1。
AC代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, m, i, j;
scanf("%d %d",&n,&m);
if (n < 2 || m < 2) {
printf("0\n");
}
else {
printf("%d\n",n*m/2-1);
if (n % 2 == 1) //判断行数是否为奇数
{
for (i = m - 1; i >= 1; i -= 2)
{
printf("%d %d\n", 1, i);
}
}
for (i = n - 1; i >= 1; i -= 2)
{
for (j = m - 1; j >= 2; j--)
{
printf("%d %d\n", i, j);
}
}
for (i = n - 1; i >= 1; i--)
{
if (i < 2 && n % 2 == 1)
break;
printf("%d %d\n", i, 1);
}
}
return 0;
}
J - Architect of Your Own Fortune
二分图匹配,直接套模板(匈牙利算法)。
先用数组存每个字符串的前三个和后三个的和,然后看谁和谁能匹配。
AC代码
#include <bits/stdc++.h>
using namespace std;
int n, m;
char s1[110][10], s2[110][10];
int q1[110], h1[110], q2[110], h2[110];
int rel[110][110], memory[110], vic[110];
int AT[110][110] = { 0 }, TA[110][110] = { 0 };
bool f(int x)
{
int i;
for (i = 0; i < m; i++)
{
if (rel[x][i] && !memory[i])
{
memory[i] = 1;
if (vic[i] == -1 || f(vic[i]))
{
vic[i] = x;
return true;
}
}
}
return false;
}
int main()
{
//freopen("Input.txt", "r", stdin);
//freopen("Output.txt", "w", stdout);
memset(vic, -1, sizeof(vic));
memset(rel, 0, sizeof(rel));
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> s1[i];
for (int i = 0; i < m; i++)
cin >> s2[i];
for (int i = 0; i < n; i++)
{
q1[i] = s1[i][0] - '0' + s1[i][1] - '0' + s1[i][2] - '0';
h1[i] = s1[i][3] - '0' + s1[i][4] - '0' + s1[i][5] - '0';
}
for (int i = 0; i < m; i++)
{
q2[i] = s2[i][0] - '0' + s2[i][1] - '0' + s2[i][2] - '0';
h2[i] = s2[i][3] - '0' + s2[i][4] - '0' + s2[i][5] - '0';
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (q1[i] == h2[j])
{
rel[i][j] = 1;
AT[i][j] = 1;
}
if (h1[i] == q2[j])
{
rel[i][j] = 1;
TA[i][j] = 1;
}
}
}
int max = 0;
for (int i = 0; i < n; i++)
{
memset(memory, 0, sizeof(memory));
if (f(i))max++;
}
cout << max << endl;
for (int i = 0; i < m; i++)
{
if (vic[i] != -1)
{
if (AT[vic[i]][i] == 1)
cout << "AT " << s1[vic[i]] << " " << s2[i] << endl;
else if (TA[vic[i]][i] == 1)
cout << "TA " << s2[i] << " " << s1[vic[i]] << endl;
}
}
return 0;
}
/*2 2
123456 111222
141204 555000*/
比赛的时候这个题没A,主要是匈牙利没记牢,还需加强训练。
总结
这次组队赛思路有些乱,模板题没记住模板,读题还是太慢,英语阅读能力还需要加强。加油!!!