您的位置:首页 > 其它

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)

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: