比赛链接:https://ac.nowcoder.com/acm/contest/35213#question
C语言版题解
- 出题小剧场
- A. 3509(对于转义字符的考察)
- B. 金牌选手的训练方式(字符串匹配)
- C. ACM金牌选手的做题顺序(数组计数)
- D. 六合数(循环)
- E. 倒背圆周率(循环)
- F. 倒背圆周率再续(字符串模拟)
- G. 所谓的签到题
- H. Wsc的魔盒(数学题)
对于特殊字符的输出需要在符号前加 来转义
#includeB. 金牌选手的训练方式(字符串匹配)#include int main(){ printf("(lll¬ω¬) (\"ω\") wmxNP!!!"); return 0; }
#includeC. ACM金牌选手的做题顺序(数组计数)#include #include char s[1000005], t[1000005]; int main(){ scanf("%s %s", s, t); int lens = strlen(s), lent = strlen(t), res = 0; for(int i = 0; i < lens; i++){ int flag = 1; for(int j = 0; j < lent; j++){ if(i+j < lens && s[i+j] == t[j]) continue; else flag = 0; } if(flag) res++; } printf("%d", res); return 0; }
由题得:把用时短的题面放在前边,再依次统计即可。
对于 1e6 的数据,使用 sort 函数可以不超时实现排序。
但是,这不是考察重点,浅浅的提供一个C语言版的解题思路:
如图所示,现在我们有五个写有编号的球和五个有编号的桶:
把每个小球放到对应编号的桶中:
把小球依次拿出来:
此时,小球就按编号依次排好序了~~
ps: 1 0 6 ∗ 1 0 6 = 1 0 12 > 2147483647 10^6 * 10 ^ 6 = 10 ^{12} > 2147483647 106∗106=1012>2147483647
#includeD. 六合数(循环)#include #include int a[1000005], v[1000005]; int main(){ int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n; i++) v[a[i]]++; long long res = 0, sum = 0; for(int i = 1; i <= 1e6; i++){ while(v[i]){ sum += i; res += sum; v[i]--; } } printf("%lld", res); return 0; }
循环判断即可。只有一个六合数:548834
#includeE. 倒背圆周率(循环)#include #include int main(){ for(int i = 1e5; i < 1e6-1; i++){ int num = 0, x = i; while(x){ num += pow(x%10, 6); x /= 10; } if(num == i) printf("%dn", i); } return 0; }
细节一:处理负数和前导零。
细节二:2147483647 -> 7463847412
细节三:int 的范围为:-2147483648 ~ 2147483647
展开讲讲细节三,如图(
亿点点小细节)
#includeF. 倒背圆周率再续(字符串模拟)#include #include int main(){ long long m; scanf("%lld", &m); if(m < 0){ m = -m; printf("-"); } long long res = 0; while(m){ res = res * 10 + m % 10; m /= 10; } printf("%lld", res); return 0; }
字符串模拟加法。
#includeG. 所谓的签到题#include #include char a[1000005], b[1000005]; int main(){ scanf("%s %s", a, b); int lena = strlen(a), lenb = strlen(b); for(int i = 0; i < lena/2; i++){ // 逆转 char x = a[i]; a[i] = a[lena-1-i]; a[lena-1-i] = x; } for(int i = 0; i < lenb/2; i++){ // 逆转 char x = b[i]; b[i] = b[lenb-1-i]; b[lenb-1-i] = x; } for(int i = lena; i < lenb; i++) a[i] = '0'; // 补零 for(int i = lenb; i < lena; i++) b[i] = '0'; // 补零 int len = (lena < lenb ? lenb : lena); a[len] = b[len] = '0'; for(int i = 0; i < len; i++){ int x = a[i] - '0' + b[i] - '0'; if(x > 9) a[i+1]++, x -= 10; // 进位 a[i] = x + '0'; } if(a[len] != '0') printf("%c", a[len]); // 判断最高位是否进位 for(int i = len-1; i >= 0; i--) printf("%c", a[i]); return 0; }
本场的防AK题。
贪心,分析可得只会重复购买一种奶茶。
枚举购买那些奶茶,再处理亿点点细节。
#includeH. Wsc的魔盒(数学题)using namespace std; typedef long long ll; const int N=1000010; ll sum[N],a[N],b[N],c[N]; void Test() { ll n,m; ll res=0; cin>>m>>n; for(int i=1; i<=n; i++) cin>>a[i]>>b[i]; for(int i=1; i<=n; i++) c[i]=a[i]; sort(c+1,c+1+n); for(int i=1; i<=n; i++) sum[i]=sum[i-1]+c[i]; c[n+1]=0x3f3f3f3f; for(int i=1; i<=n; i++) { int x=lower_bound(c+1,c+2+n,b[i])-c; if(x==n+1){ res=max(res,a[i]+(m-1)*b[i]); continue; } if(n-x+1>=m) { res=max(res,sum[n]-sum[n-m]); continue; } ll num=x; ll tmp=sum[n]-sum[num-1]; int ans=m-(n-num+1); if(a[i] ios::sync_with_stdio(false); int t; cin>>t; while(t--) Test(); return 0; }
对于有缘人最初的选择:无上智慧的概率为
1
3
frac {1}{3}
31 ,无尽财富的概率为
2
3
frac {2}{3}
32。
根据规则,
- 如果有缘人第一次选择到无尽财富,改变选择一定会选到无上智慧。
- 如果有缘人第一次选择到无上智慧,改变选择一定会选到无尽财富。
- 综上,有缘人改变选择后,得到无上智慧的概率为 2 3 frac {2}{3} 32 ,无尽财富的概率为 1 3 frac {1}{3} 31。
ps:要注意浮点误差和四舍五入。
#include#include #include void f(char x, int y){ while(y--) printf("%c", x); } int main(){ f('0', 1); f('.', 1); f('3', 20); f('n', 1); f('0', 1); f('.', 1); f('6', 19); f('7', 1); return 0; }



