比赛题目已上传到CF:2022 CCPC Henan Provincial Collegiate Programming Contest
比赛排名:Live: 2022年河南省第四届CCPC大学生程序设计竞赛 | RankLand (algoux.org)
喜提银牌一枚
这道题我队友从A题开始往后看,直接发现是道签到题,上去就开写,为了防止罚时,我们一起检查了一遍,不希望在小事在出错。最后一发A了。哈哈。
思路:构造
n >10
,你们肯定不存在,因为要保证数位中各个数字不相同。n <= 10
比赛时AC代码
#include
using namespace std;
#define int long long
signed main()
{
int n;
cin >> n;
if (n > 10)
cout << -1 << endl;
else
{
if (n == 1)
{
cout << 1 << endl;
}
else
{
cout << "10";
for (int i = 2; i < n; i++)
{
cout << i;
}
cout << endl;
}
}
return 0;
}
过了一会发现E题过了很多,觉得肯定是道签到题,然后队长让我看,我上去一看发现还真是。
思路:贪心
首先,我们需要现在字符串从前到后找到5个相同字符,然后再再剩下的字符串中找7个字符,再然后在剩下的找5个相同字符,最后就找到了一个正确结果。
为啥这样保证一定正确呢:当时我想的是如果我从字符串的第一位开始找,如果某个字母出现了5次,那么它就一定是最优的,并且只用到了整个字符串最短的部分,那么剩下的同理。
比赛时AC代码
#include
using namespace std;
#define int long long
int cnt[26];
signed main()
{
int n;
string s;
cin >> n >> s;
string res = "";
int ok = 0;
for (int i = 0; i < n; i++)
{
cnt[s[i] - 'a']++;
if (cnt[s[i] - 'a'] == 5 and ok == 0)
{
ok = 1;
res += string(5, s[i]);
for (int j = 0; j < 26; j++)
cnt[j] = 0;
}
else if (cnt[s[i] - 'a'] == 7 and ok == 1)
{
ok = 2;
res += string(7, s[i]);
for (int j = 0; j < 26; j++)
cnt[j] = 0;
}
else if (cnt[s[i] - 'a'] == 5 and ok == 2)
{
ok = 3;
res += string(5, s[i]);
break;
}
}
if (ok == 3)
cout << res << endl;
else
cout << "none" << endl;
return 0;
}
刚开始看这道题的时候感觉这道肯定是个签到提,但是这个题我们当时都犯浑了,一直在想着怎么找规律,但找的规律都不对,一开始发现了所有奇数都可以构造出来,答案是1 2 3...
。然后去想怎么构造偶数的,但发现2和4都构造不出来,是不是有其他偶数也构造不出来,然后去尝试6,8,10…,等等,就这样过了一个多小时还没写出来,但是都有点崩溃了,我当时内心都已经不能平静下去了,但已经过了两三百人了,自己不可能写不出来吧,然后队友构造出来了偶数8的构造为1 2 3 5
,然后我就想着看看以这个为突破口,然后突然发现它和奇数的规律好像,都是把最后一位加了1,然后我就去测试10,发现就是这样,当时激动的快哭了。
1 2 3 4
2 3 4 5 6 7 8
1 2 3 5
2 3 4 5 6 7 8 10
然后交了一发A了。激动坏了。差点银牌都没了,就卡在这一道签到题上了。
比赛时AC代码
#include
using namespace std;
#define int long long
signed main()
{
int n;
cin >> n;
if (n & 1)
{
int m = (n + 1) / 2;
cout << m << endl;
for (int i = 0; i < m; i++)
{
cout << i << " ";
}
cout << endl;
}
else
{
if (n == 2 or n == 4)
cout << -1 << endl;
else
{
int m = n / 2;
cout << m << endl;
for (int i = 1; i < m; i++)
{
cout << i << " ";
}
cout << m + 1 << endl;
}
}
return 0;
}
这道题也是签到题,队长先发现了这道题,看过的人也挺多,然后发现和概率有关,顿时就犯了难,因为关于概率的问题都特别难。但是当时已经过了几十个人了,就想着不可能太难。最后发现概率是个幌子,一点没用。这道题和概率没有任何关系。纯粹是迷惑人的。最后队长一发A了。不得不说这题真是妙啊。
思路:枚举
题目的本意是将n个字符串想与,最后统计字符串中有多少个1,直接枚举即可。
比赛时AC代码
#include
using namespace std;
#define int long long
string s[1010];
int cnt[4010];
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> s[i];
for (int j = 1; j <= m; j++)
{
if (s[i][j - 1] == '1')
cnt[j]++;
}
}
int q;
cin >> q;
while (q--)
{
int a, b, l, r, p;
cin >> a >> b >> l >> r >> p;
}
int res = 0;
for (int i = 1; i <= m; i++)
{
if (cnt[i] == n)
res++;
}
cout << res << endl;
return 0;
}
这题是队长首先看到的,我俩都觉得这题不难,肯定能写,但当时只有一个人过,并且很多人都wa了,心想不可能这么难吧,然后就开始写,首先想的是Acwing里的AcWing 1131. 拯救大兵瑞恩这道题,想着还记录状态,但写完了之后提交wa了,然后发现光记录每个格子的状态有没有经历过不行,因为每个水管必须只能更改一次方向,而且只能走一次,所以不能记录状态,然后队长重写了一遍,但越来越复杂,写了四百多行,最后提交还是wa了,然后我突然想到bfs不行,拿dfs可不可以,然后计算了一下复杂度,最后发现由于水管的特殊形态,所以最多只有几种走法,大约是O(n)
的复杂度,所以一定不会超时,然后我就提醒队长让他用dfs写,然后十分钟不到就写完并提交A了,我们当时贼激动,太艰难了,终究是过了,一下上到银牌了。
思路:DFS
每次搜的时候记录每个位置有没有走过,如果走过就不能在走,如果出界了也就不能在走了。走完之后还要回溯回来,为了换个路径寻找。
I
:只能从上一个过来的方向直走L
: 从上一个过来的方向向它的两边走比赛时AC代码
#include
using namespace std;
#define int long long
const int N = 1e5 + 10;
char g[3][N];
bool st[3][N];
int n = 4, m, ex, ey;
// 1 是往下走,2是往左走,3是往上走,4是往右走
bool dfs(int x, int y, int k)
{
if (x == 3 and y == ey)
return true;
if (x < 1 or x > 2 or y < 1 or y > m or st[x][y])
return false;
st[x][y] = true;
bool t;
if (g[x][y] == 'I')
{
if (k == 1)
t = dfs(x + 1, y, 1);
else if (k == 2)
t = dfs(x, y - 1, 2);
else if (k == 3)
t = dfs(x - 1, y, 3);
else
t = dfs(x, y + 1, 4);
}
else
{
if (k == 1 or k == 3)
{
t = (dfs(x, y - 1, 2) || dfs(x, y + 1, 4));
}
else if (k == 2 or k == 4)
{
t = (dfs(x - 1, y, 3) || dfs(x + 1, y, 1));
}
}
st[x][y] = false;
return t;
}
void solve()
{
cin >> m >> ex >> ey;
for (int i = 1; i <= 2; i++)
{
string s;
cin >> s;
for (int j = 1; j <= m; j++)
{
st[i][j] = false;
g[i][j] = s[j - 1];
}
}
if (dfs(1, ex, 1))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
signed main()
{
freopen("in.in", "r", stdin);
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
比赛的时候只写了这五道题,剩下的能补的尽快补上。