【YSYZ OI 】Round 2 出题纪实搬题纪实
第一次给小学初中生的同学们出题还是正式一点(指的是自己出数据,没有直接用洛谷的高级团队服务)。从2023年12月4日23:30肝到2023年12月5日2:30.整整3个小时。 写了如下目录树的文件 先是写了一份喜闻乐见的比赛说明.md,耗时半个小时。 然后开始搬运T1,改了一下题目描述,写了T1的题目描述.md,耗时十分钟。具体内容如下
game
题目描述
和
在玩一个小游戏。假设当前玩家得到一个整数
。轮到玩家时,该玩家可以对这个数加
或者减
。
先开始。如果
操作后,可以被
整除,那么他就赢了,输出
。如果已经玩了
轮了,而
还没有赢,那么
就赢了,此时输出
。
输入格式
输入第一行是一个整数,代表有
组测试数据。 对于每组测试数据,只包含一个整数
。
输出格式
输出共行,对于每一行:如果
赢,就输出
,如果
赢,输出
。
样例 #1
样例输入 #1
1
1
样例输出 #1
First
样例 #2
样例输入 #2
6
1
3
5
100
999
1000
样例输出 #2
First
Second
First
First
Second
First
提示
对于 的数据,保证
。
对于 的数据,保证
。
对于 的数据,保证
。
对于 的数据,保证
。 然后对着题目描述造数据,写了一个造数据的程序in.cpp,耗时5分钟,如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
char in[50]="2.in";
string s,t;
srand(time(0));
for(int i=1;i<=10;i++)
{
sprintf(in,"data//%d.in",i);
freopen(in,"w",stdout);
if(i<=1)
{
int t=1,x=rand()%3+1;
cout<<t<<endl;
cout<<x<<endl;
}
else if(i<=3)
{
int t=10,x;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
cout<<rand()%100+1<<endl;
}
}
else if(i<=9)
{
int t=10,x;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
long long x=rand();
cout<<x*x*x%(int(1e9))+1<<endl;
}
}
else
{
int t=10,x;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
long long x=rand(),mo=1e18;
cout<<x*x*x*x%mo+1<<endl;
}
}
}
return 0;
}
然后新建std.cpp,copy直接的AC代码,耗时1分钟。代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
long long n;
cin>>t;
while(t--)
{
cin>>n;
if((n+1)%3==0||(n-1)%3==0) cout<<"First"<<endl;
else cout<<"Second"<<endl;
}
return 0;
}
创建data文件夹,放数据用。然后分别运行in.cpp,std.cpp。分别产生了10个.in文件。以及std.exe,一定要运行std.cpp产生std.exe,因为待会儿的out.cpp要调用它。 接下来新建out.cpp,如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
char in[50]="2.in",out[50];
string s,t;
for(int i=1;i<=10;i++)
{
sprintf(in,"data//%d.in",i);
sprintf(out,"data//%d.out",i);
freopen(in,"r",stdin);
freopen(out,"w",stdout);
system("std.exe");
}
return 0;
}
OK,T1搞定 开始出T2
play
题目描述
Bramble_Marshall和Writer_TV在玩一个小游戏。游戏规则如下:每场游戏有很多局,每局游戏比分先到的人赢下这一局,每场游戏先胜
局的人获胜(可以参考乒乓球比赛理解)。
在旁边看他们玩游戏,但是
看得太入迷了,以至于忘记了
和
的具体数值。只记得他们比了
局,以及每局获胜的人,请你判断整场最后谁获胜了,如果
Bramble_Marshall获胜了,请输出,如果
Writer_TV获胜了,请输出。如果都有可能,请输出
。
输入格式
输入第一行是一个整数,代表有
组测试数据。 对于每组测试数据,先输入一个整数
,代表比了
局。接下来一行有
个包含
或者
的字符。表示对应的局是谁赢了。
输出格式
输出共行,对于每一行:如果
Bramble_Marshall获胜了,请输出,如果
Writer_TV获胜了,请输出。如果都有可能,请输出
。
样例 #1
样例输入 #1
1
5
ABBAA
样例输出 #1
A
样例 #2
样例输入 #2
2
3
BBB
7
BBAAABA
样例输出 #2
B
A
样例 #3
样例输入 #3
4
20
AAAAAAAABBBAABBBBBAB
1
A
13
AAAABABBABBAB
7
BBBAAAA
样例输出 #3
B
A
B
A
样例1解释
考虑取值的可能性: 如果
,意思是到
分就赢一小局,每场先赢
局的人胜利,显然第一局第一个人赢,第二局第二、三局第二个人赢,第四、五局第一个人赢,由于第一个人先赢三局,故输出
如果
,意思是先拿
分就赢一一局,每场先赢
局的人胜利,显然第一局第一个人赢,由于第一个人先赢一局,已经赢了,故输出
可以证明,
并没有其它取值的可能性,综上所述,输出
。
数据范围
对于 的数据,保证
。
对于 的数据,保证
且字符串中的字符全部为
或
。
对于 的数据,保证
。 t2的in.cpp。out.cpp和T1的一样就不放了。 std.cpp:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
string s;
cin>>n>>s;
cout<<s[s.size()-1]<<endl;
}
return 0;
}
记得每道题都要新建data文件夹放数据。
#include<bits/stdc++.h>
using namespace std;
int main()
{
char in[50]="2.in";
string s,t;
srand(time(0));
for(int i=1;i<=10;i++)
{
sprintf(in,"data//%d.in",i);
freopen(in,"w",stdout);
if(i<=1)
{
int t=1,x=rand()%3+1;
cout<<t<<endl;
cout<<2<<endl;
cout<<"AA"<<endl;
}
else if(i<=3)
{
int t=10,n=20;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
cout<<n<<endl;
char a='A';
if(rand()%2) a='A';
else a='B';
for(int k=1;k<=n;k++) cout<<a;
cout<<endl;
}
}
else
{
int t=10000,n=20;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
cout<<n<<endl;
char a='A';
for(int k=1;k<=n;k++)
{
if(rand()%2) a='A';
else a='B';
cout<<a;
}
cout<<endl;
}
}
}
return 0;
}
T3:
play
题目描述
有一行盒子,有些盒子是实心的,有些盒子是空的,他希望把所有空的盒子都灌上水,为此可以进行下面的两种操作:
- 1 在一个空的盒子上灌水
- 2 把一个装有水的盒子的水倒到另一个空盒子中。
如果在某个时刻,第个盒是空的,且第
和
个盒子都是装有水的盒子,则它会立刻被灌上水,而且第
和
个盒子的水不会消失。请使用最少的操作1次数把所有空盒子灌上水。你不用管操作2的次数。注意实心盒子无需灌水也无法灌水。
输入格式
输入第一行是一个整数,代表有
组测试数据。 对于每组测试数据,先输入一个整数
,代表比了
局。接下来一行有
个包含'.'或者'#'的字符。'.'表示对应的盒子是空的,'#'的表示对应的盒子是实心的。
输出格式
输出共行,对于每一行:输出最小的操作1次数。
样例 #1
样例输入 #1
1
3
...
样例输出 #1
2
样例 #2
样例输入 #2
2
7
##....#
7
..#.#..
样例输出 #2
2
5
样例 #3
样例输入 #3
2
4
####
10
#...#..#.#
样例输出 #3
0
2
样例1解释
先把第1和第3个盒子分别用操作1灌水,然后由于第1和第3个盒子有水,第2个盒子也会有水,这样所有盒子都有谁,使用了两次操作1。可以证明这是最少操作1的次数。
样例2解释
第一组测试数据,先把第3和第5个盒子分别用操作1灌水,然后由于第3和第5个盒子有水,第4个盒子也会有水。再用操作2把第4个盒子的水倒到第6个盒子中,然后由于第3和第5个盒子有水,又会把第4个盒子灌满。此时所有空心盒子都灌了水,使用了2次操作1。 第二组测试数据,显然要一个个灌,故而输出5。
数据范围
对于 的数据,保证
。
对于 的数据,保证
且保证字符串中的字符全部为
。
对于 的数据,保证
。 T3的std:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m;
void solve()
{
cin>>n;
string s;
cin>>s;
int ans=0,tot=0,f=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='#')
{
if(tot>2) f=1;
else ans+=tot;
tot=0;
}
else tot++;
}
if(tot>2) f=1;
else ans+=tot;
if(f) cout<<2<<endl;
else cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
T3的in.cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
char in[50]="2.in";
string s,t;
srand(time(0));
for(int i=1;i<=10;i++)
{
sprintf(in,"data//%d.in",i);
freopen(in,"w",stdout);
if(i<=1)
{
int t=1,x=rand()%3+1;
cout<<t<<endl;
cout<<2<<endl;
cout<<".#"<<endl;
}
else if(i<=3)
{
int t=10,n=rand()%100+1;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
n=rand()%100+1;
cout<<n<<endl;
for(int k=1;k<=n;k++) cout<<'.';
cout<<endl;
}
}
else
{
int t=100,n=100;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
cout<<n<<endl;
char a='A';
int tot=0;
for(int k=1;k<=n;k++)
{
if(rand()%2)
{
a='.';
tot++;
if(tot==3) a='#',tot=0;
}
else a='#';
cout<<a;
}
cout<<endl;
}
}
}
return 0;
}
T4:
play
题目描述
是一个喜欢数学的女孩,有一天
在黑板上写了一些数字来考她。所有数字要么是
,要么是
,要么是
。 每次操作可以选择两个不同的数字,然后擦掉它们,并写出与两个擦掉的数字不同的数字。比如,一开始黑板上有数字
,假设这次选择擦掉
,那么就必须写上
,这些数字就变成
了。
问
,在一些操作之后,黑板上有没有可能只剩下一种类型的数字。如果可能,请用指定的格式输出。
思考了许久没能找到答案,请你帮她解决这个问题吧。
输入格式
输入第一行是一个整数,代表有
组测试数据。 对于每组测试数据,固定输入
个整数
,代表黑板上写了
个
,
个
,
个
。
输出格式
输出共行,对于每一行:输出
个数,每个数只能是
或
,
表示不能剩下对应数字,
表示可以剩下对应数字。比如说输出
,表示最后只能剩下
,比如说输出
,表示最终可以剩下
或者
,但不可能剩下
。
样例 #1
样例输入 #1
1
1 1 1
样例输出 #1
1 1 1
样例 #2
样例输入 #2
1
2 3 2
样例输出 #2
0 1 0
样例 #3
样例输入 #3
1
82 47 59
样例输出 #3
1 0 0
样例1解释
一开始,黑板上有数字1,2,3。如果一开始擦掉2,3,那么最后剩下1,1。所以最后剩下的数字都是1。如果一开始擦掉1,3,那么最后剩下2,2。所以最后剩下的数字都是2。 如果一开始擦掉1,2,那么最后剩下3,3。所以最后剩下的数字都是3。故输出1 1 1。
样例2解释
一开始,黑板上有数字1,1,2,2,2,3,3。显然如果一开始擦掉1,3,那么剩下1,2,2,2,2,3。再擦掉1,3,那么最后剩下2,2,2,2,2,所以最后剩下的数字都是2。可以继续尝试,会发现无论怎么擦都不会只留下1或者3,故输出0 1 0
数据范围
对于 的数据,保证
。
对于 的数据,保证
。 T4的std:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m;
void solve()
{
int a,b,c;
cin>>a>>b>>c;
cout<<!((b+c)&1)<<" "<<!((a+c)&1)<<" "<<!((a+b)&1)<<endl;
}
int main()
{
// freopen("1900B.in","r",stdin);
// freopen("1900B.out","w",stdout);
int t;
cin>>t;
while(t--) solve();
return 0;
}
T4的in.cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
char in[50]="2.in";
string s,t;
srand(time(0));
for(int i=1;i<=10;i++)
{
sprintf(in,"data//%d.in",i);
freopen(in,"w",stdout);
if(i<=1)
{
int t=1,x=rand()%100+1;
cout<<t<<endl;
cout<<x<<" "<<x<<" "<<x<<endl;
}
else
{
int t=1e5;
cout<<t<<endl;
for(int j=1;j<=t;j++)
{
int a=rand()%100+1;
int b=rand()%100+1;
int c=rand()%100+1;
cout<<a<<" "<<b<<" "<<c<<endl;
}
}
}
return 0;
}
题解.md如下 模拟赛题解
T1
原题链接:www.luogu.com.cn/problem/CF1… 不难发现,如果第一个人+1或者减1之后不能被3整除的情况下,第二个人不是智障的话,总会把数字还原,以让第一个人还是不能赢。所以(x+1)%==0或者(x-1)%3==0的情况下,第一个人必赢,否则必输。记得开'long long',否则只能拿90分。10轮之内不能决出胜负这是个迷惑条件,小小的诈骗了一手。 一份代码实现
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
if((n+1)%3==0||(n-1)%3==0) cout<<"First"<<endl;
else cout<<"Second"<<endl;
}
return 0;
}
T2
原题链接:www.luogu.com.cn/problem/CF1… 诈骗题,故意用样例解释解释得非常详细,以带偏各位的思路。事实上,只要看最后一分是谁拿的就好了,最后一分谁拿的当然是谁赢,因为某个人赢了比赛就结束了。所以只要输出记录的最后一个字符。代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
string s;
cin>>n>>s;
cout<<s[s.size()-1]<<endl;
}
return 0;
}
T3
原题链接:www.luogu.com.cn/problem/CF1… 不难发现,如果存在连续的3个'.',那么答案就是2。 如果不存在连续的3个'.',那么答案就是'.'的总个数。 扫一遍字符串就可以了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m;
void solve()
{
cin>>n;
string s;
cin>>s;
int ans=0,tot=0,f=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='#')
{
if(tot>2) f=1;
else ans+=tot;
tot=0;
}
else tot++;
}
if(tot>2) f=1;
else ans+=tot;
if(f) cout<<2<<endl;
else cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
T4
原题链接:www.luogu.com.cn/problem/CF1… 对于任意的两个数,每次要么出现次数同时减一,要么一加一减,无论如何任意两数的次数之差(或之和)的奇偶性不变,因此猜结论:两数之差为偶数,可以只剩下第三个数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m;
void solve()
{
int a,b,c;
cin>>a>>b>>c;
cout<<!((b+c)&1)<<" "<<!((a+c)&1)<<" "<<!((a+b)&1)<<endl;
}
int main()
{
// freopen("1900B.in","r",stdin);
// freopen("1900B.out","w",stdout);
int t;
cin>>t;
while(t--) solve();
return 0;
}
本文使用 markdown.com.cn 排版