一、前情提要
在经过三天的摸鱼 学习写bug队列、优先队列和素数筛相关内容之后,参加集训的同学们终于迎来了第二场考试,在这场考试中,我会有哪些脑残操作进步呢?
总结:
1.用scanf多组输入再一次忘记’~'符号(cin/cout真香) ——OLE
2.输出格式不注意,最后一个数据只换行不空格的要求没有注意 ——PE
3.写代码不能懒手脚,不然可能在细节上面出问题 ——WA
4.根据题目数据量与数据大小,如果有加/乘运算的话需要推断是不是long long才装的下 ——WA
5.当你在林大OJ上做题提交后发现RE,但是你又觉得自己代码没问题的话,你就要看是不是用了自爆装置ios::sync_with_stdio(false) 取消同步了,这玩意在林大OJ上玄学出问题 ——RE
6.当你发现有的题是找对应关系输出答案的而且只是TLE的话……那么你完全可以试一下打表啊哈哈哈 ——⭐AC⭐
二、习题&题解(共七题)
格式:题号-题名-AC/Submit
A 机器人 [60/146]
这题比较简单
#include <bits/stdc++.h>
using namespace std;
struct xxx //存x以及对应翻转后的值
{
int x, x2;
} xx;
bool operator<(const xxx &a, const xxx &b)
{
if (a.x2 != b.x2)
return a.x2 > b.x2;
else
return a.x > b.x;
}
priority_queue<xxx, vector<xxx>, less<xxx>> s;
int get_x(int t) //翻转操作
{
int k = 0, s = t, m = 1, g, h = 0;
while (s)
{
s = s / 10;
k++;
}
while (k)
{
for (int i = 1; i < k; i++)
m = m * 10;
k--;
g = (t % 10) * m;
t = t / 10;
m = 1;
h = h + g;
}
return h;
}
int main()
{
int n, x, tt;
while (~scanf("%d", &n)) //注意scanf的多组输入!!
{
for (int i = 1; i <= n; i++)
{
scanf("%d", &x);
tt = get_x(x);
s.push({x, tt});
}
for (int i = 1; i <= n; i++)
{
if (i < n)
printf("%d ", s.top().x);
else
printf("%d\n", s.top().x);
s.pop();
}
}
//system("pause");
return 0;
}
B 纸牌游戏 [68/165]
这个挺简单的
#include <bits/stdc++.h>
using namespace std;
queue<int> s;
int main()
{
int n, x;
cin >> n;
while (n--)
{
cin >> x;
if (x == 1)
{
cout << x << endl;
continue;
}
for (int i = 1; i <= x; i++)
s.push(i);
while (s.size() != 1)
{
if (s.size() > 2)
cout << s.front() << ",";
if (s.size() == 2)
cout << s.front() << endl;
s.pop();
s.push(s.front());
s.pop();
}
cout << s.front() << endl;
s.pop();
}
//system("pause");
return 0;
}
C 咸鱼连突刺 [37/289]
啊啊啊这题气死我了!!
以为mark[0]默认=0就想着偷下懒没再赋0,忘记经过memset都成1了,然后一直WA,疯狂检查一个多小时主函数不知道错在哪直到时间结束。
偷懒两秒钟,卡题一小时。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6;
bool mark[N + 1];
int prime[N + 1];
int t, l, r;
ll ans;
void get_prime()
{
int cnt = 0;
memset(mark, 1, sizeof(mark));
mark[0]=mark[1] = 0;//就是这里!!考试的时候只写了mark[1]=0!!!
for (int i = 1; i <= N; i++)
{
if (mark[i])
prime[++cnt] = i;
for (int j = 1; j <= cnt; j++)
{
if (i * prime[j] > N)
break;
mark[i * prime[j]] = 0;
if (i % prime[j] == 0)
break;
}
}
}
int main()
{
scanf("%d", &t);
get_prime();
while (t--)
{
ll la = 0, ra = 0;
scanf("%d %d", &l, &r);
for (int i = l; i <= r; i++)
{
if (mark[i])
{
la = i;
break;
}
}
for (int i = r; i >= l; i--)
{
if (mark[i])
{
ra = i;
break;
}
}
ll ttt = la + ra;
ans += ttt;
}
printf("%lld\n", ans);
//system("pause");
return 0;
}
D 库特的合并果子 [58/313]
在林大OJ上我都不敢用ios::sync_with_stdio(false)了,简直就是自爆指令,随机RE竟恐怖如斯。
数据量大还是老老实实scanf、printf吧。
这题交了三次一是没注意格式,二是没仔细推断数据类型(“第一行是一个整数 n(2≤n≤200000) ,表示果子的种类数。第二行包含 n 个整数,用空格分隔,第 i 个整数 ai(1≤ai ≤1000000) 是第 i 种果子的数目。”这一推就是要用long long才能装的下啊喂(#`O′))
#include <bits/stdc++.h>
using namespace std;
long long n, t, cnt;
priority_queue<long long, vector<long long>, greater<long long> > s;
int main()
{
while (~scanf("%lld", &n))
{
for (int i = 1; i <= n; i++)
{
scanf("%lld", &t);
s.push(t);
}
int pos = 1;
while (s.size() != 1)
{
cnt = s.top();
s.pop();
cnt += s.top();
s.pop();
if (pos < n - 1)
printf("%lld ", cnt);
if (pos == n - 1)
printf("%lld\n", cnt);
s.push(cnt);
pos++;
}
s.pop();
}
//system("pause");
return 0;
}
E 库特的素数队列(1) [32/125]
F 库特的素数队列(2) [17/76]
这两题好玩哈哈哈哈,题解是一样的,不是我说,表一打好数据量再翻几倍也没关系啊
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t, x;
int str[20] = {2, 3, 5, 11, 31, 127, 709, 5381, 52711, 648391, 9737333};
cin >> t;
while (t--)
{
cin >> x;
if (x == 1)
cout << "1" << endl;
if (x == 2)
cout << "2" << endl;
if (x >= 3 && x <= 4)
cout << "3" << endl;
if (x >= 5 && x <= 10)
cout << "5" << endl;
if (x >= 11 && x <= 30)
cout << "11" << endl;
if (x >= 31 && x <= 126)
cout << "31" << endl;
if (x >= 127 && x <= 708)
cout << "127" << endl;
if (x >= 709 && x <= 5380)
cout << "709" << endl;
if (x >= 5381 && x <= 52710)
cout << "5381" << endl;
if (x >= 52711 && x <= 648390)
cout << "52711" << endl;
if (x >= 648391 && x <= 9737332)
cout << "648391" << endl;
if (x >= 9737333)
cout << "9737333" << endl;
}
//system("pause");
return 0;
}
附上打表代码初版(需要稍微改动才能打,不过改的代码我没保存~~)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7;
int prime[N + 1], num[N + 1], str[1000001];//num用来记录从1到n之间的素数个数,str是用来存数的数组
bool mark[N + 1];
void screen()
{
int cnt = 0;
memset(mark, 1, sizeof(mark));
mark[0] = mark[1] = 0;
num[1] = 0;
for (int i = 2; i <= N; i++)
{
if (mark[i])
prime[++cnt] = i;
for (int j = 1; j <= cnt; j++)
{
if (i * prime[j] > N)
break;
mark[i * prime[j]] = 0;
if (i % prime[j] == 0)
break;
}
num[i] = cnt; //记录
}
}
int main()
{
int t, n;
screen();
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = 1; i <= num[n]; i++) //根据num的记录直接找出素数存入str
str[i] = prime[i];
int pos = num[n];
while (pos != 1) //循环记录素数,用pos计数
{
int poss = pos;
pos = 0;
for (int i = 1; i <= poss; i++)
{
if (mark[i])
{
str[++pos] = str[i];
}
}
}
printf("%d\n", str[1]);
}
//system("pause");
return 0;
}
G 库特的绳子 [7/57]
被C卡了时间以致于没写到这,现在累了想追剧了,先鸽了吧§( ̄▽ ̄)§