Codeforces Round #506 (Div. 3) D-F
阿新 • • 發佈:2018-08-26
with while 長度 難度 滿足 clu || ted return
Codeforces Round #506 (Div. 3) (中等難度)
自己的做題速度大概只嘗試了D題,不過TLE
D. Concatenated Multiples
題意
- 數組a[],長度n,給一個數k,求滿足條件的(i,j)(i!=j) a[i],a[j]連起來就可以整除k
- 連起來的意思是 20,5連起來時205; 5,20連起來時520
- n<=2*1e5,k<=1e9,ai<=1e9
- 愚蠢的思路是像我一樣遍歷(i,j)可能性,然後TLE,因為這是O(n^2)
- 可以先思考一簡單問題如何不是連起來而是a[i]+a[j]如何計算,很簡單將a[]%k進行計數,然後計數(k-a[i])%k,這時查找只需O(logn)
- 這裏a[i]*(10^k),k實際上只有10中可能所以也可以存起來
時間復雜度O(nlogn)
代碼
#include<bits/stdc++.h> const int maxn=200020; #define ll long long int a[maxn]; int mod[maxn]; int ka[maxn]; int n,k; int geth(int x){ ll mul=1; int t=1; while(mul<=x){ mul=mul*10; t=(t*(10%k))%k; } return t; } int main(){ scanf("%d %d",&n,&k); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); mod[i]=a[i]%k; ka[i]=(geth(a[i]))%k; } ll ans=0; for(int i=1;i<=n;i++){//O(n^2) for(int j=1;j<=n;j++){ if(i!=j&&((mod[i]*(ka[j]))%k+mod[j])%k==0){ //printf("db %d %d\n",i,j); ans++; } } } printf("%I64d\n",ans); }
E. Tree with Small Distances
題意
這道題還沒想出來,據說使用貪心,下面是別人代碼(感覺大佬的思路都是一樣,應該是觸摸到問題本質)
代碼
#include<bits/stdc++.h> using namespace std; int n; const int maxn = 2e5+100; vector<int> G[maxn]; int used[maxn]; int d[maxn]; int ans = 0; void dfs(int u,int f){ //cout<<"enter"<<u<<" "<<f<<endl; bool flag = false; for(int i=0;i<G[u].size();i++){ int v = G[u][i]; if(v!=f){ d[v] = d[u] + 1; dfs(v,u); flag|=used[v]; } } if(d[u]>2&&!used[u]&&!flag&&!used[f]){ used[f] = true; //cout<<"db"<<f<<endl; ans++; } //cout<<"out"<<endl; } int main(){ int t; //freopen("in.txt","r",stdin); scanf("%d",&n); for(int i=0;i<n-1;i++){ int a,b; scanf("%d%d",&a,&b); G[a].push_back(b); G[b].push_back(a); } dfs(1,0); /* cout<<"db1\n"; for(int i=1;i<=n;i++){ cout<<d[i]<<"\t"; } cout<<endl; for(int i=1;i<=n;i++){ cout<<used[i]<<"\t"; } cout<<"db over"<<endl; */ printf("%d\n",ans); //fclose(stdin); return 0; }
F. Multicolored Markers
題意
- 自己看題吧
枚舉較短邊,考慮藍方塊構成矩形的最低高度和紅方塊構成矩形的最低高度是否和當前高度沖突
代碼
#include<bits/stdc++.h>
#define ll long long
int main(){
ll a,b;
std::cin>>a>>b;
ll c=a+b;
ll tmp=std::max(a,b);
ll minl=(a+b+1)*2;
ll lowa=a;
ll lowb=b;
for(ll i=1;i*i<=(a+b);i++){
if(a%i==0) lowa=a/i;
if(b%i==0) lowb=b/i;
if(c%i==0){
if(c/i>=lowa||c/i>=lowb){
//std::cout<<"db"<<i<<std::endl;
minl=std::min(2*(i+c/i),minl);
}
}
}
std::cout<<minl<<std::endl;
}
加油,需要補題Kmp,數論+樹
Codeforces Round #506 (Div. 3) D-F