2017 icpc 瀋陽現場賽
阿新 • • 發佈:2018-11-22
題目:連結
F Heron and His Triangle:
暴力跑了幾發,把搞出來的數扔進oeis裡發現對於條件成立的t陣列
有t[i]=4*t[i-1]-t[i-2]。因此找到第一個大於等於N的t[i]就好了。
但是數值範圍超過了long long,因此要用大數,這樣一個個找
過去會超時,可以先對詢問排序,這樣下次的詢問就可以接著
上次的位置尋找。
程式碼:
#include<bits/stdc++.h> using namespace std; int a[105][33],c[105],ans[30003]; int T; char t[105]; struct node { int k[33],id; }g[30003]; bool cmp(const node &x,const node &y) { for(int i=32;i>=0;i--) if(x.k[i]!=y.k[i]) return x.k[i]<y.k[i]; } void init() { a[0][0]=4;a[1][0]=4;a[1][1]=1; for(int i=2;i<=100;i++) { int x=0; for(int j=0;j<=32;j++) { a[i][j]=4*a[i-1][j]-a[i-2][j]+x; if(a[i][j]>=0) { x=a[i][j]/10; a[i][j]%=10; } else { x=-1; a[i][j]=10+a[i][j]; } } } } bool compare(int now,int i) { for(int j=32;j>=0;j--) if(a[now][j]!=g[i].k[j]) return a[now][j]>g[i].k[j]; return 1; } void work() { int now=0; for(int i=1;i<=T;i++) { while(!compare(now,i)) now++; ans[g[i].id]=now; } } int main() { init(); scanf("%d",&T); for(int i=1;i<=T;i++) { g[i].id=i; scanf("%s",&t); int len=strlen(t); for(int j=0;j<len;j++) g[i].k[j]=t[len-j-1]-'0'; } sort(g+1,g+T+1,cmp); work(); for(int i=1;i<=T;i++) { int id=ans[i],j=32; while(a[id][j]==0) j--; for( ;j>=0;j--) printf("%d",a[id][j]); printf("\n"); } return 0; }
I Little Boxes:
大數加法:
#include<bits/stdc++.h> using namespace std; int a[33],b[33]; char t[33]; void add() { int c[33]; memset(c,0,sizeof(c)); int len=strlen(t+1); for(int i=1;i<=len;i++) c[i]=t[len-i+1]-'0'; int k=0; for(int i=1;i<33;i++) { a[i]=a[i]+c[i]+k; k=a[i]/10; a[i]%=10; } } int main() { int T;scanf("%d",&T); while(T--) { memset(a,0,sizeof(a)); for(int i=1;i<=4;i++) { scanf("%s",t+1); add(); } int id=32; while(id>1&&a[id]==0) id--; for( ;id>=1;id--) printf("%d",a[id]); printf("\n"); } return 0; }
K Rabbits:
只有a[1]~a[2]或a[n-1]~a[n]跳不到,其他都能跳到。
程式碼:
#include<bits/stdc++.h> using namespace std; const int maxn=505; int a[maxn]; int main() { int T;scanf("%d",&T); while(T--) { int n;scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int mi=min(a[2]-a[1]-1,a[n]-a[n-1]-1); //for(int i=2;i<=n;i++) mi=min(mi,a[i]-a[i-1]-1); printf("%d\n",a[n]-a[1]+1-n-mi); } return 0; }
L Tree:
考慮一條邊把整個圖分成兩部分,若這兩部分的點的個數都大於k則這條邊可行。
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
vector<int>G[maxn];
int n,k,son[maxn],ans;
void dfs(int v,int fa)
{
son[v]=1;
for(int i=0;i<G[v].size();i++)
{
int to=G[v][i];
if(to==fa) continue;
dfs(to,v);
son[v]+=son[to];
if(son[to]>=k&&n-son[to]>=k) ans++;
}
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=0;i<=n;i++) G[i].clear();
ans=0;
for(int i=1;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1,0);
printf("%d\n",ans);
}
return 0;
}