A
link
先判断一下时间是否跨天,如果跨天了,把后一个加上\(24\),使后一个大于前一个,再判断国王喊的时间或喊的时间加\(24\)是否在范围内。
神奇的代码
#include<bits/stdc++.h>
using namespace std;
signed main(){
int a,b,c;
cin >> a >> b >> c;
if(b > c) c += 24;
if(b <= a&&a <= c||b <= a+24&&a+24 <= c) cout << "No";
else cout << "Yes";
return 0;
}
B
link
输入后再用\(cout\)输出即可,因为\(cout\)会去掉末尾的\(0\)。
神奇的代码
#include<bits/stdc++.h>
using namespace std;
signed main(){
double x;
cin >> x;
cout << x;
return 0;
}
C
link
搜索即可,每个数按从小到大搜,输出的一定是字典序从小到大的。
神奇的代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
int r[10];
int sum,res[10];
void dfs(int x){
if(x > n){
if(sum%k == 0){
for(int i = 1;i <= n;++ i)
cout << res[i] << " ";
cout << endl;
}
return;
}
for(int i = 1;i <= r[x];++ i){
res[x] = i;
sum += i;
dfs(x+1);
sum -= i;
}
}
signed main(){
cin >> n >> k;
for(int i = 1;i <= n;++ i) cin >> r[i];
dfs(1);
return 0;
}
D
link
化环为链。
我们把长度为\(n\)的环变为长度为\(2n\)的链,这样环上能走的链上也都能走,但是会有重复,那么我们针对后半部分,看它为\(t\)时哪些\(s\)满足要求。
这里如果是\(s\)走到\(t\),那么路程就是\(qzh_{t-1}-qzh_{s-1}\),\(qzh_i\)为\(a_i\)的前缀和,后半部分也一样做前缀和,但是要把前半部分的\(a_i\)也累加上。解释一下为什么是\(qzh_{t-1}-qzh_{s-1}\),因为\(a_i\)就可以走到\(i+1\)了,那么加到\(qzh_{t-1}\)就可以走到\(t\)了,然后\(qzh_{s-1}\)是走到\(s\)的,这一部分不需要。
首先,考虑如果在环上的要求:从前边段这个的后面走到它才行,否则会有绕圈。其次,考虑是\(m\)的倍数的要求,我们知道如果\((qzh_{t-1}-qzh_{s-1})%m=0\),那么\(qzh_{t-1}%m=qzh_{s-1}%m\),所以,对于每一个\(n+t\)(因为是后半段),我们只要找在\(t+1\)及以后的\(s\)中\(qzh_{s-1}%m\)和\(qzh_{t-1}%m\)一样的个数即可,那么我们可以转化为\(t+1\)及以后的\(s\)中\(qzh_s%m\)和\(qzh_{t}%m\)一样的个数。
那么我们可以用一个桶存\(%m\)的余数的个数,一开始把所有前半段的都加上,然后每次把前半段的这一个去掉(前面那些已经在前面去掉了),计入答案后把这一个加上,如果先加了会多,因为\(s\)不能是自己。
神奇的代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
int a[200005];
int qzh[400005];
int g[1000005];
int ans;
signed main(){
cin >> n >> m;
for(int i = 1;i <= n;++ i){
cin >> a[i];
qzh[i] = (qzh[i-1]+a[i])%m;
}
for(int i = 1;i <= n;++ i){
qzh[n+i] = (qzh[n+i-1]+a[i])%m;
}
for(int i = 1;i <= n;++ i) g[qzh[i]]++;
for(int i = n+1;i <= 2*n;++ i){
g[qzh[i-n]]--;
ans += g[qzh[i]];
g[qzh[i]]++;
}
cout << ans;
return 0;
}