USACO Roundabount Rounding 题解
~哇噢,第一次打 USACO 就能写题解。~
思路
观察题目我们可以发现:对于一个整数数
对于 Elsie 的“链式舍入”而我们可以把
当
Bessie 和 Elsie 舍入的方法我们都知道了,问题就迎刃而解了。
我们用一个布尔数组
代码
注意点
-
-
- 注意数组越界。
#include <bits/stdc++.h>
using namespace std;
int t, cnt, ln=44; // ln 指最长的 N 从 44 开始因为这之前都没有不一致的
bitset<1000000009> arr;
pair<int, pair<int, int> > n[114514]; // 离线操作用来存 N 的数组 第一个是 N 第二个是读入时的编号 第三个是答案
int ans[114514]; // 离线操作用来存答案的数组
int main() {
for(int xi=10; xi<=pow(10, 9)/5; xi*=10) { // 计算是否一致
for(int i=xi*4+5; i<xi*5; i++) {
if(i-xi*4>=xi/2 || (arr.test(i-xi*4) && i-xi*4>=xi/10)) { // 用上面的方法
arr.set(i, true);
}
}
}
cin>>t;
for(int i=0; i<t; i++) { // 看,离线操作是不是很烦
cin>>n[i].first;
n[i].second.first=i;
}
sort(n, n+t);
for(int i=0; i<t; i++) {
for(int j=ln+1; j<=n[i].first; j++) cnt+=arr.test(j);
n[i].second.second=cnt;
ln=n[i].first;
}
for(int i=0; i<t; i++) {
ans[n[i].second.first]=n[i].second.second;
}
for(int i=0; i<t; i++) { // 输出
cout<<ans[i]<<endl;
}
return 0;
}