题目全部来自于往年省赛
题目A. 机器人足球
足球场地长为 100,宽为 20,对方的球门坐标为(100,10),你要控制一个机器人 踢球,初始位置为(x,y)。机器人可以朝任何方向移动,但不能超出场地边界。当 机器人与球门距离不超过 10 时,可以射门。问机器人从初始位置出发到射门, 最少要移动多少距离?(四舍五入到小数点后 3 位)
解题思路:
根据输入的坐标,判断该坐标和球门的距离,在根据距离和10比较,判断此时能否射门,如果不能射门,输出需要移动的距离。
具体解法:
计算平面上两点之间的距离,判断是否大于10,如果小于10,则直接输出0.000,如果大于10,则用距离减去10,输出差,是最少移动距离。
#include<stdio.h>
#include<math.h>
int main(void)
{
int x,y;
float way;
scanf("%d %d",&x,&y);
x = 100-x;
y = y-10;
way = sqrt(x*x+y*y);
if (way<=10)
{
printf("0.000");
}
else
{
printf("%.3f",way-10);
}
return 0;
}
题目B.纸牌识别
Alice 沉迷于机器人研究,他打算做一个机器人来检查一副扑克是否完整。现在, 他想请你帮他写一个程序,来识别纸牌。每张纸牌都有一个花色(四种花色,分 别用大写字母 P,K,H,T 表示)和一个数字点数(1-13)。纸牌可以用 ABC 的形式来表示,A 代表花色,BC 代表数字,如果数字小于 10,会有一位补 0。 比如花色是 P,数字是 9 的纸牌会表示成 P09。一副完整的纸牌有 52 张牌,四 种不同的花色各有 1 张数字 1-13 的牌。 你的程序要读入一个字符串,表示缺少的纸牌有哪些。如果包含相同的纸牌(花 色数字都相同)输出 GRESKA,否则输出每种花色剩余的纸牌数量。
解题思路:
创建一个字符数组用于储存输入的字符串,建立一个二维数组用于储存输入的纸牌数据,记录相应纸牌的出现次数。如果有纸牌出现两次或两次以上,则直接输出“GRESKA”。如果输入的纸牌不包含相同的,则统计每种花色剩余纸牌的数目,并输出。
具体解法:
输入符合要求的字符串,判断每张纸牌的出现次数,再统计输入纸牌的数量,如果在统计过程中,发现某张纸牌的出现次数大于或等于2,则直接输出“GRESKA”,并结束运行,如果没有出现该情况,则完成统计,通过循环输出每一种花色剩余纸牌的数量。
#include<stdio.h>
#include<string.h>
int main(void)
{
char s[1000];
int j[5][14];
int num[5];
int i,k,leng;
int sum;
scanf("%s",s);
leng = strlen(s);
for(i=1;i<5;i++)
{
for(k=1;k<14;k++)
{
j[i][k] = 0;
}
num[i] = 0;
}
for(i=1;i<leng;i=i+3)
{
sum = (s[i]-'0')*10+(s[i+1]-'0');
if(s[i-1]=='P')
{
j[1][sum]++;
}
else if(s[i-1]=='K')
{
j[2][sum]++;
}
else if(s[i-1]=='H')
{
j[3][sum]++;
}
else
{
j[4][sum]++;
}
}
for(i=1;i<5;i++)
{
for(k=1;k<14;k++)
{
if(j[i][k]==1)
{
num[i]++;
}
else if(j[i][k]>1)
{
printf("GRESKA");
return 0;
}
}
}
for(i=1;i<5;i++)
{
printf("%d ",13-num[i]);
}
return 0;
}
题目J.密信
Alice 想给 Bob 发短信,短信的内容可以看成是一个只有小写字母的字符串 p; 为了加密短信,Alice 需要只有小写字母长度为 n 的字符串 h,并且 p 是 h 的子 串;Alice 想知道,这样的字符串有多少种。 给出 n 和 M 还有字符串 p,假设一共有 K 种不同的 h,输出 K mod M
解题思路:
运用动态规划和矩阵优化,统计出字符串的数量,再用总数除以输入的M,得出最终的结果。
具体解法:
先输入执行的次数,然后输入字符串的长度,和后面需要除以的M,再得出需要加密的字符串的长度。运用定义的函数gf和结构体,最终算出最终的结果。
#include<stdio.h>
#include<string.h>
typedef long long ll;
typedef unsigned long long ull;
int f[50],len;
int t;
long long n,m;
char s[50];
void gf()
{
int j = 0;
for(int i=1;i<=len-1;i++){
while (j&&s[j]!=s[i])
{
j=f[j];
}
if (s[j]==s[i])
{
++j;
}
f[i+1] = j;
}
}
ull qmul(const ull a, const ull b, const ull md) {
ll c=(ll)a*b-(ll)((ull)((long double)a*b/md)*md);
return c<0?md+c:((ull)c>md?c-md:c);
}
struct Mat {
ll v[55][55];
Mat() {memset(v, 0, sizeof v);}
Mat operator * (const Mat& b) const {
Mat c;
for(int k=0;k<=len;k++)
for(int i=0;i<=len;i++)
for(int j=0;j<=len;j++){
c.v[i][j] = (qmul(v[i][k],b.v[k][j],m)+c.v[i][j])%m;
}
return c;
}
Mat operator ^ (ll nn) {
Mat b, a=*this;
for(int i=0;i<=len;i++)
b.v[i][i]=1;
while(nn) {
if(nn&1LL) b=b*a;
nn>>=1LL,a=a*a;
}
return b;
}
};
int main(void)
{
scanf("%d",&t);
while(t>0)
{
scanf("%lld %lld %s",&n,&m,s);
len = strlen(s);
gf();
Mat g;
for(int i=0;i<=len;i++)
for(int k='a';k<='z';k++) {
int nxt = i;
while (nxt&&s[nxt]!=k) nxt = f[nxt];
if (s[nxt]==k) ++nxt;
if (i==len) nxt = len;
++g.v[nxt][i];
}
g = g^n;
printf("%lld\n", g.v[len][0]);
t--;
}
}