希望更丰富的阅读体验?点这里
一、题解
A.Plural Form
题目大意
对于一个长度小于等于 1000 1000 1000 的单词,输出其负数形式(如果以s结尾,则变为复数时要加es,否则加s)。
分析
人口普查题。
代码
#include <cstdio>
#include <cstring>
char s[1003];
int main(){
scanf("%s",s);
printf("%s",s);
if(s[strlen(s)-1]=='s') puts("es");
else puts("s");
return 0;
}
B.Go to Jail
题目大意
高桥扔了 N N N ( 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100)组骰子,每组中他又扔了 2 2 2 次骰子。问是否会出现连续三组中每组扔的两次骰子点数一样的情况,是就输出Yes,否则输出No。
分析
签到题,因为 N N N 很小,所以直接暴力判断。
代码
#include <cstdio>
int n,d[103][3];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&d[i][1],&d[i][2]);
for(int i=3;i<=n;i++)
if(d[i][1]==d[i][2]&&d[i-1][1]==d[i-1][2]&&d[i-2][1]==d[i-2][2])
return puts("Yes"),0;
return puts("No"),0;
}
C.A x B + C
题目大意
找出有多少个正整数 A , B , C A,B,C A,B,C 满足 A × B + C = N ( 1 ≤ N ≤ 1 0 6 ) A \times B+C=N(1 \le N \le 10^6) A×B+C=N(1≤N≤106) 。
分析
如果 A × B + C = N A \times B+C=N A×B+C=N ,则必须满足 A × B < N A \times B<N A×B<N 。因为这么算 A , B A,B A,B 最大等于 1 0 3 10^3 103 ,所以直接枚举 A , B A,B A,B 就好了。
代码
#include <cstdio>
int main(){
int n,ans=0;
scanf("%d",&n);
for(int a=1;a<=n;a++)
for(int b=1;b*a<n;b++)//这里边界要优化,否则会超时
++ans;
printf("%d\n",ans);
return 0;
}
D.Leaping Tak
题目大意
有一行格子,编号从 1 1 1 到 N N N( 2 ≤ N ≤ 2 × 1 0 5 2 \le N \le 2 \times 10^5 2≤N≤2×105)。给出 K K K 个不相交闭区间( 1 ≤ K ≤ m i n ( K , 10 ) 1 \le K \le min(K,10) 1≤K≤min(K,10)),用 L i , R i L_i,R_i Li,Ri 表示,设 S S S 为这些区间的并集。
高桥站在 1 1 1 号位置,每一次他可以从 S S S 中选出一个元素 d d d ,往后跳 d d d 格。如果他最后想正好跳到 N N N 号位置,问路径的方案总数,结果对 998244353 998244353 998244353 取模。
分析
设 f [ i ] f[i] f[i] 表示走到 i i i 的方案数。
对于每一条线段,都有 f [ i ] = f [ i ] + f [ i − L ] + f [ i − ( L + 1 ) ] + f [ i − ( L + 2 ) ] + … + f [ i − R ] f[i]=f[i]+f[i-L]+f[i-(L+1)]+f[i-(L+2)]+\dotsc+f[i-R] f[i]=f[i]+f[i−L]+f[i−(L+1)]+f[i−(L+2)]+…+f[i−R](大于 L L L 小于 R R R 的所有点都在并集内)。
所以需要一个前缀和数组 s [ i ] s[i] s[i] 维护 f [ 1 ] + f [ 2 ] + … + f [ i ] f[1]+f[2]+\dotsc+f[i] f[1]+f[2]+…+f[i] ,代码很好写。
代码
#include <cstdio>
#define mod 998244353
#define max(a,b) ((a)>(b)?(a):(b))
struct interval{
int l,r;
}a[200003];
long long f[200003]={0,1},s[200003]={0,1};
int n,k;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++) scanf("%d%d",&a[i].l,&a[i].r);
for(int i=2;i<=n;i++){
for(int j=1;j<=k;j++)
if(i>a[j].l)
f[i]=(f[i]+(s[i-a[j].l]-s[max(i-a[j].r-1,0)])%mod)%mod;//注意取模
s[i]=(s[i-1]+f[i])%mod;
}
printf("%lld\n",f[n]%mod);
return 0;
}
但这份代码会WA掉四个点,把输出改为(f[n]+mod)%mod就行了,可能f[n]为负数要修正?
E.Sequence Sum
有空来补题。