Gym 101097I Sticks (思维)
2017-04-27 23:48
507 查看
题意:
给出至多 50 种颜色的共 1e6 根木棍,问是否能有 3 支颜色不同的木棍可以拼成三角形。
思路:
首先注意可能爆 int 的细节。
队里三个人都在做这道题,结果三个人都思维江化僵化,拖了很久。
结果三个人写了三种代码,都是 AC 的,事后证明三个人的思路原理是一样的。
所以以下贴三种代码,各是各的思路。
首先都是按长度排序
A 和 B 的思路近似于构造一个存有三种不同颜色的木棍的框。
每次加入一根新的木棍时,若新棍的颜色与框内重复,则保留同色最大的。
若不重复,则删除框中长度最小的,加入新棍。
每次加入判断是否符合题意即可。
C 的思路和 A B 原理相同。
枚举每个木棍,找到与其长度最接近(不妨规定为大于等于)并且颜色不同的木棍。
这时候就得到了两根木棍,可以推算出第三根木棍的合法长度区间。
从 50 - 2 种颜色中二分寻找是否有符合条件的木棍即可。
代码:
A 同学的:O(n*k)
B 同学的:O(n)
C同学的:O(n*k)
给出至多 50 种颜色的共 1e6 根木棍,问是否能有 3 支颜色不同的木棍可以拼成三角形。
思路:
首先注意可能爆 int 的细节。
队里三个人都在做这道题,结果三个人都思维江化僵化,拖了很久。
结果三个人写了三种代码,都是 AC 的,事后证明三个人的思路原理是一样的。
所以以下贴三种代码,各是各的思路。
首先都是按长度排序
A 和 B 的思路近似于构造一个存有三种不同颜色的木棍的框。
每次加入一根新的木棍时,若新棍的颜色与框内重复,则保留同色最大的。
若不重复,则删除框中长度最小的,加入新棍。
每次加入判断是否符合题意即可。
C 的思路和 A B 原理相同。
枚举每个木棍,找到与其长度最接近(不妨规定为大于等于)并且颜色不同的木棍。
这时候就得到了两根木棍,可以推算出第三根木棍的合法长度区间。
从 50 - 2 种颜色中二分寻找是否有符合条件的木棍即可。
代码:
A 同学的:O(n*k)
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; int k,n,cur,num[55],s[55]; struct node { int color,len; bool operator<(struct node &T) { if(len!=T.len) return len<T.len; else return color<T.color; } }e[1000005]; bool pd(int a,int b,int c) { if(a==-1||b==-1||c==-1) return 0; if(a+b>c&&a+c>b&&b+c>a) { for(int i=1;i<=k;i++) { if(num[i]==a) { cout<<i<<" "<<a<<" "; num[i]=-1; break; } } for(int i=1;i<=k;i++) { if(num[i]==b) { cout<<i<<" "<<b<<" "; num[i]=-1; break; } } for(int i=1;i<=k;i++) { if(num[i]==c) { cout<<i<<" "<<c<<endl; break; } } return 1; } return 0; } void updatejian(int m) { int w=lower_bound(s+1,s+k+1,m)-s; for(int i=w;i<=k;i++) s[i]=s[i+1]; } bool updatejia(int m) { int w=lower_bound(s+1,s+k+1,m)-s; for(int i=k+1;i>w;i--) s[i]=s[i-1]; s[w]=m; if(w!=1&&w!=2) if(pd(s[w-2],s[w-1],s[w])) return 1; if(w!=1&&w!=k) if(pd(s[w-1],s[w],s[w+1])) return 1; if(w!=k&&w!=k-1) if(pd(s[w],s[w+1],s[w+2])) return 1; return 0; } int main() { freopen("sticks.in","r",stdin); freopen("sticks.out","w",stdout); bool flag; while(cin>>k) { cur=0; flag=1; memset(num,-1,sizeof(num)); memset(s,-1,sizeof(s)); for(int i=1;i<=k;i++) { cin>>n; for(int j=1;j<=n;j++) { e[cur].color=i; scanf("%d",&e[cur++].len); } } s[k+1]=1000000001; sort(e,e+cur); for(int i=0;i<cur;i++) { //cout<<num[e[i].color]<<endl; updatejian(num[e[i].color]); num[e[i].color]=e[i].len; if(updatejia(num[e[i].color])) { flag=0; break; } } if(flag) cout<<"NIE"<<endl; } return 0; }
B 同学的:O(n)
#include <iostream> #include <vector> #include <queue> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; struct p{ int num; long long l; bool operator <(p a)const{ return l<a.l; } }; vector <p> v; p data[3]; bool ck(int s,p t){ for (int k=0;k<s; ++k) if(data[k].num==t.num) return false; return true; } void huan(p t){ for (int i=0; i<2; ++i) data[i]=data[i+1]; data[2]=t; } int main(int argc, const char * argv[]) { freopen("sticks.in","r",stdin); freopen("sticks.out","w",stdout); int k,n,tol; p t; while (scanf("%d",&k)==1) { v.clear();tol=0; for (int i=1; i<=k; ++i) { scanf("%d",&n); tol+=n; for (int j=0; j<n; ++j) { t.num=i; scanf("%lld",&t.l); v.push_back(t); } } int s=0;bool ok=false; sort(v.begin(),v.end()); for (int i=0; i<tol; ++i) { if (!s) data[s++]=v[i]; else if(s<3){ if(ck(s, v[i])) data[s++]=v[i]; else { if (v[i].num==data[0].num) data[0]=data[1]; data[1]=v[i]; } } else{ if(ck(s,v[i])) huan(v[i]); else{ for (k=0; k<3; ++k) { if (data[k].num==v[i].num) { for (int j=k; j<2; ++j) data[j]=data[j+1]; data[2]=v[i]; } } } } if (s==3) { if (data[0].l+data[1].l>data[2].l) { ok=true; cout<<data[0].num<<" "<<data[0].l<<" "<<data[1].num<<" "<<data[1].l<<" "<<data[2].num<<" "<<data[2].l<<endl; break; } } } if (!ok) puts("NIE"); } return 0; }
C同学的:O(n*k)
#include <bits/stdc++.h> using namespace std; const long long INF=0x3f3f3f3f3f3f3f3f; typedef struct Node{ long long x; int col; bool operator < (const Node &a)const{ return x<a.x; } }Node; int n,m; long long x; vector <long long> co[55]; vector <long long>::iterator it,it1,it2; Node a[(int)1e6+100]; int main(){ scanf("%d",&n); bool flag=0; int ppp=0; for(int i=0;i<n;i++){ scanf("%d",&m); co[i].clear(); for(int j=0;j<m;j++){ scanf("%lld",&x); co[i].push_back(x); a[ppp].x=x;a[ppp].col=i; ppp++; } } for(int i=0;i<n;i++) sort(co[i].begin(),co[i].end()); sort(a,a+ppp); int ban1=-1,ban2=-1; long long now=-1,ans1,anscol1,ans2,anscol2,l,r,ans0,anscol0; for(int i=0;i<ppp;i++){ ans0=a[i].x;anscol0=a[i].col; ban1=a[i].col; ans1=INF;ans2=INF; for(int j=0;j<n;j++){ if(j!=ban1){ it=lower_bound(co[j].begin(),co[j].end(),ans0); if(it!=co[j].end()){ now=*it; if(ans1>now){ ans1=now; anscol1=j; } } } } ban2=anscol1; l=ans1-ans0; r=ans1+ans0; for(int j=0;j<n;j++){ if(j!=ban1&&j!=ban2){ it1=lower_bound(co[j].begin(),co[j].end(),r); it2=upper_bound(co[j].begin(),co[j].end(),l); if((it2!=co[j].end())&&it1!=it2){ ans2=*it2; anscol2=j; flag=1; break; } } } if(flag) break; } if(flag) cout<<anscol0+1<<' '<<ans0<<' '<<anscol1+1<<' '<<ans1<<' '<<anscol2+1<<' '<<ans2<<endl; else cout<<"NIE"<<endl; }
相关文章推荐
- Gym - 101097I Sticks(思维)
- GYM 101128 C.Canvas Painting【思维+优先队列】
- Gym 100801E Easy Arithmetic (思维题)
- codeforces gym 101142 F(思维)
- Gym-100781A 【树的直径 + 思维】
- I - Por Costel and the Pairs Gym - 100923I _思维啊——可惜我现在还没
- GYM - 100812B Set of Tasks (思维好题)
- Gym - 100971B-思维-特殊情况
- GYM 101128 A.Promotions【思维+暴力】
- Gym 100801D Distribution in Metagonia (数学思维题)
- Gym - 101572D Distinctive Character bfs + 思维 好题
- B - Weird Cryptography Gym - 100935B(集合,思维题)
- 思维题 Gym 100553A Alter Board
- Gym - 101061A 思维题
- UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There Was One / POJ 3517 And Then There Was One / Aizu 1275 And Then There Was One (动态规划,思维题)
- Gym - 101503J Numbers Painting(素数分解+思维)
- 翻译题-思维-Gym - 101341C
- Problem D. Dales and Hills - Gym - 101411D 【动态规划经典题 - 思维】
- Gym 101572D Distinctive Character【思维+Bfs】
- GYM - 100812G Short Path (SPFA+思维)