NEFU大一省赛训练2 (A B C D E F G I J)

OP

\

A Alphabet Cookies

字符串处理

思路

统计字母数后比对,保证没有字母不足;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int n,ap[26];
string g;
while(cin>>n)
{
memset(ap,0,sizeof ap);
cin>>g;
for(int i=0;g[i];i++)
{
ap[g[i]-'A']++;
}
int f=1;
cin>>g;
for(int i=0;g[i];i++)
{
ap[g[i]-'A']--;
if(ap[g[i]-'A']<0)f=0;
}
if(f)printf("Yes\n");
else printf("No\n");
}
return 0;
}

B Sequential game

模拟

思路

按要求模拟即可

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
string g;
while(cin>>g)
{
int zero=0,one=0;
if(g[0]=='1')one++;
else zero++;
for(int i=1;g[i];i++)
{
if(g[i]!=g[i-1])
{
swap(one,zero);
}
if(g[i]=='1')one++;
else zero++;
}
printf("%d %d\n",zero,one);
}
return 0;
}

C The Hardest Problem Ever

字符串处理

思路

按要求操作即可

思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
string g;
while(cin>>g)
{
if(g!="START")break;
getchar();
getline(cin,g);
for(int i=0;g[i];i++)
{
if(g[i]>='A'&&g[i]<='Z')
{
g[i]=(g[i]-'A'-5+26)%26+'A';
}
printf("%c",g[i]);
}
printf("\n");
cin>>g;
}
return 0;
}

D Dart game

dp

思路

建立两个dp空间,一个存储使用一倍,两倍和三倍的方案数,另一个存储只使用一倍和三倍的方案数;

这两个再作差即为目标分数的合法方案数,因为只要整个方案中存在使用过两倍的情况,便可以将这个两倍移至最后,方案即合法;

注意DP的细节,不可以在一次循环中同时dp一倍,二倍与三倍,推测是与后效性限制有关;

注:所有的可行值是1-20的1-3倍,和25的1-2倍,想玩的可以去洛圣都体验一下hhh;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=2011;
int main()
{
int a[1100]={0},b[1100]={0};
a[0]=1,b[0]=1;
for(int k=1;k<=21;k++)//遍历1-20及25
{
if(k==21)k=25;
for(int kk=1;kk<=3;kk++)//遍历3倍
{
if(k==25&&kk==3)break;//25没有三倍
for(int i=1;i<=1001;i++)
{
if(i>=k*kk)a[i]+=a[i-k*kk];
if(i>=k*kk&&kk!=2)b[i]+=b[i-k*kk];
a[i]%=M,b[i]%=M;
}
}
}
int n;
while(cin>>n&&n)
{
printf("%d\n",(a[n]-b[n]+M)%M);
}
return 0;
}

E Similar Word

字符串处理

思路

把一个串在后面加上自身后,循环对比即可;

如果两串长度不同则不可能为相似串;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=2011;
int main()
{
string g,g1;
int a[26];
while(cin>>g)
{
cin>>g1;
int f=1;
if(g==g1)f=0;
g=g+g;
if(g.length()/2!=g1.length())f=0;
int i;
for(i=0;g1[i];i++)
{
if(!g.compare(i,g1.length(),g1))break;
}
if(!g1[i])f=0;
if(f)printf("yes\n");
else printf("no\n");
}
return 0;
}

F Post office

中位数

思路

特别像货仓选址问题;

在O(1)的时间复杂度内确定邮局的位置后,遍历区间求距离和,不会TLE;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=2011;
int main()
{
int n;
ll pos[1003];
while(~scanf("%d",&n))
{
if(!n)break;
memset(pos,0,sizeof pos);
memset(frt,0,sizeof frt);
for(int i=1;i<=n;i++)
{
scanf("%lld",&pos[i]);
}
scanf("%d",&n);
int l,r;
while(n--)
{
scanf("%d%d",&l,&r);
ll ans=0;
for(int i=l;i<=r;i++)
{
ans+=abs(pos[i]-pos[l+r>>1]);
}
printf("%lld\n",ans);
}
}
return 0;
}

G Lucky Boy

几何,博弈

思路

首先确定好统计共线的方法;

对于任意两点,一定共线;
对于每一条直线,我们可以用斜截式定义并用map<pair<double,double>,int>储存,经测试,不存在斜率不存在的直线,无浮点误差影响(数据可加强);

由规则来说,每次操作需要拿走共线的任意个点(≥1)也就是说,如果场上存在三点共线的情况,则a必赢;
如果不存在三点共线的情况,则此时的博弈即为以下状况:

场上存在n个点,a先手,每人次可以拿走1个或2个点,取走最后一个点者赢;

那么此时,如果场上有3n个点,则后手者可以控制使每次场上他拿完后仍剩余3n个点,即先手必输;
如果场上有3*n+1或3*n+2个点,则先手者可以取走1个或2个点,使场上剩余3*n个点,情况即变为先后手对换的上种情况,此时后手必输;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=2011;
map<pair<double,double>,int>mp;
pair<ll,ll> p[1003];
int main()
{
int n;
while(~scanf("%d",&n))
{
mp.clear();
int i,j;
for(i=1;i<=n;i++)
{
scanf("%lld%lld",&p[i].first,&p[i].second);
}
int ff=0;
for(i=1;i<=n&&!ff;i++)
for(j=i+1;j<=n&&!ff;j++)
{
{
double k=(p[j].second-p[i].second)*1.0/(p[j].first-p[i].first)
,b=p[i].second-k*p[i].first;
if(mp[{k,b}]==1)ff++;
mp[{k,b}]++;
}
}
if(ff||n%3)printf("a is the lucky boy.\n");
else printf("b is the lucky boy.\n");
}
return 0;
}

H Car race game

搜了一下题解,好像还要用到线段树之类的,感觉比较麻烦(懒),以后再来探索吧。

I Jiulianhuan

数学

思路

之前也没有玩过,赛后找了好多视频也没搞清楚怎么解的;

最后还是感谢sl大佬找的资料,如下:
来自知乎
在这里插入图片描述

高中数学书666;

注:题给数据有一些问题,1005的返回值应该是4260;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=10007;
int qm(int a,int b)
{
int ans=1;
for(;b;b>>=1)
{
if(b&1)ans=ans*a%M;
a=a*a%M;
}
return ans;
}
int main()
{
int n;
while(cin>>n)
{
cout<<(qm(2,n+1)-2+(n&1)+M)*qm(3,M-2)%M<<endl;
}
return 0;
}

J The minimum square sum

打表,数学

思路

个人是ph大佬带我打表找规律,不过他要证一下,大家可以拭目以待hh;

结论可以从AC代码中直接读出来,在此不多赘述了;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=2011;
int main()
{
ll n;
while(cin>>n)
{
if(n==2)printf("2\n");
else if((n+1>>1)&1)printf("%lld\n",n);
else printf("%lld\n",n*n*2);
}
return 0;
}

打表代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M=2011;
int main()
{
int i,j,k;
for(i=3;i<=49;i+=2)
{
for(j=1;j<=200;j++)
{
for(k=j;k<=200;k++)
{
if((j*j+k*k)%i==0){printf("%d %d\n",i,(j*j+k*k));goto aa;}
else if((j*j+k*k)>i)break;
}
}
aa:
i=i;
}
return 0;
}

ED

实际上应该有一个 NEFU大一省赛训练3 的,但是那一场自己做得实在太水了,在此仅做标记。


NEFU大一省赛训练2 (A B C D E F G I J)
https://tanyuu.github.io/2021.01-06/NEFU大一省赛训练2 (A B C D E F G I J)/
作者
F Juny
发布于
2021年5月4日
许可协议