人生第一場 AtCoder,紀念一下
話說年后的 AtCoder 比賽怎么這么少啊(大霧
AtCoder Beginner Contest 154 題解
A - Remaining Balls
We have A balls with the string S written on each of them and B balls with the string T written on each of them.
From these balls, Takahashi chooses one with the string U written on it and throws it away.
Find the number of balls with the string S and balls with the string T that we have now.
Solution
#include <bits/stdc++.h>
using namespace std;
int a,b;
string s,t,u;
int main() {
cin>>s>>t>>a>>b>>u;
if(s==u) cout<<a-1<<" "<<b<<endl;
else cout<<a<<" "<<b-1<<endl;
}
B - I miss you...
Given is a string S. Replace every character in S with x and print the result.
Solution
算一下字符串長度即可,理論上按char讀進來逐個輸出應該更短
#include <bits/stdc++.h>
using namespace std;
string s;
int main() {
cin>>s;
for(int i=0;i<s.length();i++) cout<<"x";
}
C - Distinct or Not
Given is a sequence of integers \(A_1, A_2, ..., A_N\). If its elements are pairwise distinct, print YES; otherwise, print NO.
Solution
排序應該是比較優雅的方法吧,雖然感覺 std::map 會更短
不對,這 \(1024MB\)的內存,是不是暴力開桶不用壓位都能過
#include <bits/stdc++.h>
using namespace std;
int a[200005],n;
int main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<n;i++) {
if(a[i]==a[i+1]) {
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
}
D - Dice in Line
We have \(N\) dice arranged in a line from left to right. The \(i\)-th die from the left shows \(p_i\) numbers from \(1\) to \(p_i\) with equal probability when thrown.
We will choose \(K\) adjacent dice, throw each of them independently, and compute the sum of the numbers shown. Find the maximum possible value of the expected value of this sum.
Solution
根據期望的線性性質,很容易發現只要求個最大區間和就可以了。怎么求呢,前綴和啊。
因為沒加fixed數字大時飄成科學計數法 WA 了一發,我 TM 真是個憨憨。
#include <bits/stdc++.h>
using namespace std;
int n,k,p[200005];
int main() {
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>p[i], p[i]+=p[i-1];
int mx=0;
for(int i=0;i+k<=n;i++) mx=max(mx,p[i+k]-p[i]);
cout<<setiosflags(ios::fixed)<<setprecision(12)<<(k+mx)*0.5;
}
E - Almost Everywhere Zero
Find the number of integers between \(1\) and \(N\) (inclusive) that contains exactly \(K\) non-zero digits when written in base ten.
\(1 \leq N < 10^{100}\),
\(1 \leq K \leq 3\)
Solution
暴力數位 dp 即可,當然可能有更簡單的方法,但我覺得推推公式什么的太麻煩了,還是直接數位 dp 吧
套路性地,設 \(f[i][j]\) 表示長度為 \(i\) 的數字串,有 \(j\) 個非零數位的方案數,轉移方程
注意 \(i=0\) 或者 \(j=0\) 的時候需要特判一下
暴力轉移預處理出 \(f[i][j]\) 后,我們來統計答案。先把 \(N\) 本身判掉,然后枚舉 \(x\) 從哪一位開始比 \(N\) 小,那么這一位之前的就全部確定了(和 \(N\) 一樣),這一位討論一下是 \(0\) 和不是 \(0\) 的情況,每種情況下,這位之后的部分都只約束了非零數字的個數,求和即可得到答案。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1005;
char str[N];
int n,k,ans,f[N][5];
signed main() {
cin>>str+1;
n=strlen(str+1);
for(int i=1;i<=n;i++) str[i]-='0';
cin>>k;
f[0][0]=1;
for(int i=1;i<=n;i++) {
f[i][0]=f[i-1][0];
for(int j=1;j<=3;j++) {
f[i][j]=f[i-1][j]+9*f[i-1][j-1];
}
}
int cnt=0;
for(int i=1;i<=n;i++) {
//Calculate a[i] = 0
if(str[i]) {
if(k-cnt>=0) ans+=f[n-i][k-cnt];
}
//Calculate a[i] > 0
if(str[i]>1) {
if(k-cnt-1>=0) ans+=(str[i]-1)*f[n-i][k-cnt-1];
}
if(str[i]) ++cnt;
}
if(cnt==k) ++ans;
cout<<ans;
}
F - Many Many Paths
Snuke is standing on a two-dimensional plane. In one operation, he can move by \(1\) in the positive x-direction, or move by \(1\) in the positive y-direction.
Let us define a function \(f(r, c)\) as follows:
\(f(r,c) :=\) (The number of paths from the point \((0, 0)\) to the point \((r, c)\) that Snuke can trace by repeating the operation above)
Given are integers \(r_1, r_2, c_1,\) and \(c_2\). Find the sum of \(f(i, j)\) over all pair of integers \((i, j)\) such that \(r_1 ≤ i ≤ r_2\) and \(c_1 ≤ j ≤ c_2\), and compute this value modulo \((10^9+7)\).
\(1 ≤ r_1 ≤ r_2 ≤ 10^6\),
\(1 ≤ c_1 ≤ c_2 ≤ 10^6\)
Solution
首先單個答案是容易求的,根據高中數學可知 \(f(i,j) = C_{i+j}^i\)
設 \(g(i,j)\) 是它的二維前綴和,那么原答案一定可以用四個 \(g(i,j)\) 的和差表示
下面考慮如何求 \(g(i,j)\),打印一張數表看一看,很容易想到沿着 \(j\) 維度方向做差試試,觀察容易得到
於是得到
考慮到 \(g(i,0)\) 是顯然的,而 \(f(i,j)\) 很容易做單維度遞推,即
后者用逆元處理即可,每次逆元計算(使用快速冪方法)花費 \(O(\log n)\),於是我們可以在 \(O(n \log n)\) 時間內求出 \(\sum_j f(i,j)\),即求出了 \(g(i,j)\)
總體時間復雜度 \(O(n \log n)\)
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
const int mod = 1e+9+7;
ll qpow(ll p,ll q) {
ll r = 1;
for(; q; p*=p, p%=mod, q>>=1) if(q&1) r*=p, r%=mod;
return r;
}
int inv(int p) {
return qpow(p,mod-2);
}
const int N = 1e+6+5;
int f[N],g[N];
int solve(int i,int m) {
memset(f,0,sizeof f);
memset(g,0,sizeof g);
g[0]=i+1; f[1]=i+1;
for(int k=2;k<=m+1;k++) f[k]=f[k-1]*(i+k)%mod*inv(k)%mod;
for(int j=1;j<=m;j++) g[j]=(g[j-1]+f[j+1])%mod;
return g[m];
}
signed main() {
int r1,c1,r2,c2;
cin>>r1>>c1>>r2>>c2;
--r1; --c1;
cout<<((solve(r2,c2)-solve(r1,c2)-solve(r2,c1)+solve(r1,c1)%mod+mod)%mod)<<endl;
}
