写在前面
今年国赛刚刚结束,忍不住抒发一下感想。主要就是一个重大失误和一个创造奇迹。
题解和代码(回忆版)
两道填空题一眼没思路,直接看编程题,后面也没时间再看了,扫了一眼感觉不好蒙,就空着了。
试题 C: 数字轮盘
我是在草稿纸上手动模拟来找规律,写了一页A4纸大小的草稿,花了一个半小时之久。可以发现,“操作”的作用就是将最后两个数字移到最前面。接着想办法把各种情况对应过去即可。注意,当 为偶数而
为奇数时,无法恢复原样。
#include <iostream>
using namespace std;
void solve()
{
int n,k;
cin>>n>>k;
if(k%n==0)
{
cout<<0<<'\n';
return;
}
if(n%2==1)
{
if(k%n%2==0) cout<<(2*n-k%n)/2;
else cout<<(n-k%n)/2;
cout<<'\n';
}
else
{
if(k%2==1)
{
cout<<-1<<'\n';
return;
}
cout<<(n-k%n)/2<<'\n';
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
在洛谷跑的是满分,应该问题不大。
试题 D: 斐波那契字符串
这题思路还是挺简单的,看代码即可了解,是动态规划的思想。当然,我做的时候没想什么动态规划,当成思维题做了。
然而我犯了一个重大错误。代码如下。
#include <iostream>
#define int long long
using namespace std;
const int N = 1e9 + 7;
void solve()
{
int n;
cin >> n;
int a_cnt0 = 1, a_cnt1 = 0, a_sum = 0;
int b_cnt0 = 0, b_cnt1 = 1, b_sum = 0;
int cnt0 = 0, cnt1 = 0, sum = 0;
for (int i = 3; i <= n; ++i)
{
cnt0 = (a_cnt0 + b_cnt0) % N;
cnt1 = (a_cnt1 + b_cnt1) % N;
sum = (a_sum + b_sum + a_cnt1 * b_cnt0 % N) % N;
a_cnt0 = b_cnt0;
a_cnt1 = b_cnt1;
a_sum = b_sum;
b_cnt0 = cnt0;
b_cnt1 = cnt1;
b_sum = sum;
}
cout << sum << '\n';
}
signed main()
{
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
只拿到四分之一的分,其他都超时了。问题在于,我每个测试用例都跑了一遍循环,没有想到可以先把数据范围内的所有答案跑出来存起来,这样对于每个用例,只需把答案取出来,大大节省时间。
我当时以为所有测试用例的 的总和不超过
,可能是受cf题目影响,有惯性思维了。但是蓝桥杯的这道题并不是这个意思,因此我这样写就超时了,因为
最大能到
,乘起来就是很大的数了。
修改后的代码如下。洛谷满分。
#include <iostream>
#define int long long
using namespace std;
const int N = 1e9 + 7;
int a[100005];
void init()
{
int a_cnt0 = 1, a_cnt1 = 0, a_sum = 0;
int b_cnt0 = 0, b_cnt1 = 1, b_sum = 0;
int cnt0 = 0, cnt1 = 0, sum = 0;
for (int i = 3; i <= 100000; ++i)
{
cnt0 = (a_cnt0 + b_cnt0) % N;
cnt1 = (a_cnt1 + b_cnt1) % N;
sum = (a_sum + b_sum + a_cnt1 * b_cnt0 % N) % N;
a[i] = sum;
a_cnt0 = b_cnt0;
a_cnt1 = b_cnt1;
a_sum = b_sum;
b_cnt0 = cnt0;
b_cnt1 = cnt1;
b_sum = sum;
}
}
void solve()
{
int n;
cin >> n;
cout << a[n] << '\n';
}
signed main()
{
int t;
cin >> t;
init();
while (t--)
{
solve();
}
return 0;
}
试题 E: 项链排列
这道题我是用全排列函数找规律。应该算是构造题。
#include <iostream>
#include <string>
using namespace std;
void solve()
{
int a, b, c;
cin >> a >> b >> c;
string s = "";
if (c == 0) //特判
{
if (a == 0)
{
for (int i = 1; i <= b; ++i) s += "Q";
cout << s;
return;
}
else if (b == 0)
{
for (int i = 1; i <= a; ++i) s += "L";
cout << s;
return;
}
else
{
cout << -1;
return;
}
}
if (a == b)
{
if (c > a + b - 1)
{
cout << -1;
return;
}
if (c == a + b - 1)
{
for (int i = 1; i <= a + b; ++i)
{
if (i & 1) s += "L";
else s += "Q";
}
cout << s;
return;
}
}
else
{
if (c > min(a, b) * 2)
{
cout << -1;
return;
}
if (c == min(a, b) * 2)
{
if (a > b)
{
for (int i = 1; i <= a - b - 1; ++i) s += "L";
for (int i = 1; i <= b * 2 + 1; ++i)
{
if (i & 1) s += "L";
else s += "Q";
}
cout << s;
return;
}
else
{
for (int i = 1; i <= a * 2 + 1; ++i)
{
if (i & 1) s += "Q";
else s += "L";
}
for (int i = 1; i <= b - a - 1; ++i) s += "Q";
cout << s;
return;
}
}
}
if (c % 2 == 0)
{
for (int i = 1; i <= a - c / 2 - 1; ++i) s += "L";
for (int i = 1; i <= c; ++i)
{
if (i & 1) s += "L";
else s += "Q";
}
for (int i = 1; i <= b - c / 2; ++i) s += "Q";
s += "L";
cout << s;
}
else
{
c = (c + 1) / 2;
for (int i = 1; i <= a - c; ++i) s += "L";
for (int i = 1; i <= c * 2; ++i)
{
if (i & 1) s += "L";
else s += "Q";
}
for (int i = 1; i <= b - c; ++i) s += "Q";
cout << s;
}
}
int main()
{
int t = 1;
//cin>>t;
while (t--)
{
solve();
}
return 0;
}
代码里 的特判我当时没想到,如果两种珠子数量都大于零,那么
就不能为零。比赛的时候光想着判断最大值了,推着推着就忘记最小值了。没加特判前,洛谷跑了95分,加上之后满分。

试题 F: 蓝桥星数字
看到这道题的时候,应该是没多少时间了,急忙写了个暴力。
#include <iostream>
#define int long long
using namespace std;
bool check(int n)
{
if (n < 10) return 0;
int m = n, c1, c2;
c1 = m % 10;
m /= 10;
while (m > 0)
{
c2 = m % 10;
if ((c1 % 2) == (c2 % 2)) return 0;
m /= 10;
c1 = c2;
}
return 1;
}
void solve()
{
int n;
cin >> n;
int i = 1, j = 0;
for (;; ++i)
{
if (check(i))
{
++j;
if (j == n)
{
break;
}
}
}
cout << i;
}
signed main()
{
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}

洛谷20分,其他样例都超时。
试题 G: 翻倍
这个时候只剩十分钟左右了,我都准备开摆了,但是瞄了一眼题目,感觉应该可以快速敲个暴力,于是立马动手,大概花了五分钟吧,真的极限,不知道官方测试数据水不水,在洛谷能骗一半分。
#include <iostream>
#define int long long
using namespace std;
int a[200005];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
}
int cnt = 0;
for (int i = 2; i <= n; ++i)
{
while (a[i] < a[i - 1])
{
++cnt;
a[i] *= 2;
}
}
cout << cnt;
}
signed main()
{
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}

我感觉这个真的是创造奇迹,手感来了挡都挡不住。
剩下的题目也没时间看了,大致扫一眼,感觉也没法直接输出东西来骗分,就空着了。
总结
这几个月基本没怎么做题,因此没有手感,D题犯下重大错误。不知道是不是为了弥补这个错误,做了几个小时后手感上来,G题“神救场”。其实归根结底还是要通过努力来提高实力,毕竟这是最能掌握在自己手里的。
结合洛谷,估分大概40,希望有个国三吧。没想到国赛是十道题,满分150,区分度很高。
另外,我想夸一下这次的考点——广州华南商贸职业学院,体验非常好!老师、学生、志愿者、饭堂员工等等,都非常友善。非常感谢各方人员尽力为蓝桥杯国赛保驾护航,希望他们工作顺利、生活愉快!
1179

被折叠的 条评论
为什么被折叠?



