#include "message.h" #include "krazki.h" #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define FORD(i,a,b) for(int i=(a);i>=(b);--i) #define foreach(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i) #define all(c) (c).begin(),(c).end() #define scanf(...) scanf(__VA_ARGS__)?:0 #define e1 first #define e2 second #define mp make_pair using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,int> pli; const int inf=1000000009; const ll infll=1e18+41; int id,nodes,n,m,len,pocz[105],kon[105]; ll rurka[105],krazek[105]; pli s[2540000]; pii req[11000]; int main() { id=MyNodeId(); nodes=NumberOfNodes()-1; n=PipeHeight(); m=NumberOfDiscs(); len=(max(n+1,m)-1)/nodes+1; FOR(i,1,100) pocz[i]=1+len*(i-1),kon[i]=len*i; if (id==0) { int ans=n,ireq=0; FOR(i,1,nodes) Receive(i),rurka[i]=GetLL(i),krazek[i]=GetLL(i); FOR(j,1,nodes) { int mozna=3; FOR(i,1,nodes) { if (rurka[i]<krazek[j]) { req[ireq++]=mp(i,j); if (mozna==3) mozna=2; } if (mozna<3) mozna--; if (mozna==0) break; } } REP(i,ireq) { int numer=i%nodes+1; PutInt(numer,req[i].e1); PutInt(numer,req[i].e2); Send(numer); } REP(i,ireq) { int numer=i%nodes+1; Receive(numer); ans=min(ans,GetInt(numer)); } FOR(i,1,nodes) PutInt(i,-1),Send(i); printf("%d",ans); } else { ll minrurka=infll,maxkrazek=-1; if (pocz[id]<=n+1 && kon[id]>n) minrurka=0; else FOR(i,pocz[id],min(n+1,kon[id])) minrurka=min(minrurka,HoleDiameter(i)); FOR(i,pocz[id],min(m,kon[id])) maxkrazek=max(maxkrazek,DiscDiameter(i)); PutLL(0,minrurka); PutLL(0,maxkrazek); Send(0); while (true) { Receive(0); int prurka=GetInt(0); if (prurka==-1) break; int pkrazek=GetInt(0); int d=min(n+1,kon[prurka])-pocz[prurka]+1; FOR(i,pocz[prurka],min(n+1,kon[prurka])) { if (i<=n) s[i-pocz[prurka]].e1=HoleDiameter(i); else s[i-pocz[prurka]].e1=0; s[i-pocz[prurka]].e2=i; } sort(s,s+d); FOR(i,1,d-1) s[i].e2=min(s[i].e2,s[i-1].e2); int ans=inf; FOR(i,pocz[pkrazek],min(m,kon[pkrazek])) { int ct=lower_bound(s,s+d,mp(DiscDiameter(i),0))-s; if (ct==0) continue; int poziom=s[ct-1].e2-m+i-1; if (poziom<ans) ans=poziom; } if (ans<0) ans=0; PutInt(0,ans); Send(0); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #include "message.h" #include "krazki.h" #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define FORD(i,a,b) for(int i=(a);i>=(b);--i) #define foreach(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i) #define all(c) (c).begin(),(c).end() #define scanf(...) scanf(__VA_ARGS__)?:0 #define e1 first #define e2 second #define mp make_pair using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,int> pli; const int inf=1000000009; const ll infll=1e18+41; int id,nodes,n,m,len,pocz[105],kon[105]; ll rurka[105],krazek[105]; pli s[2540000]; pii req[11000]; int main() { id=MyNodeId(); nodes=NumberOfNodes()-1; n=PipeHeight(); m=NumberOfDiscs(); len=(max(n+1,m)-1)/nodes+1; FOR(i,1,100) pocz[i]=1+len*(i-1),kon[i]=len*i; if (id==0) { int ans=n,ireq=0; FOR(i,1,nodes) Receive(i),rurka[i]=GetLL(i),krazek[i]=GetLL(i); FOR(j,1,nodes) { int mozna=3; FOR(i,1,nodes) { if (rurka[i]<krazek[j]) { req[ireq++]=mp(i,j); if (mozna==3) mozna=2; } if (mozna<3) mozna--; if (mozna==0) break; } } REP(i,ireq) { int numer=i%nodes+1; PutInt(numer,req[i].e1); PutInt(numer,req[i].e2); Send(numer); } REP(i,ireq) { int numer=i%nodes+1; Receive(numer); ans=min(ans,GetInt(numer)); } FOR(i,1,nodes) PutInt(i,-1),Send(i); printf("%d",ans); } else { ll minrurka=infll,maxkrazek=-1; if (pocz[id]<=n+1 && kon[id]>n) minrurka=0; else FOR(i,pocz[id],min(n+1,kon[id])) minrurka=min(minrurka,HoleDiameter(i)); FOR(i,pocz[id],min(m,kon[id])) maxkrazek=max(maxkrazek,DiscDiameter(i)); PutLL(0,minrurka); PutLL(0,maxkrazek); Send(0); while (true) { Receive(0); int prurka=GetInt(0); if (prurka==-1) break; int pkrazek=GetInt(0); int d=min(n+1,kon[prurka])-pocz[prurka]+1; FOR(i,pocz[prurka],min(n+1,kon[prurka])) { if (i<=n) s[i-pocz[prurka]].e1=HoleDiameter(i); else s[i-pocz[prurka]].e1=0; s[i-pocz[prurka]].e2=i; } sort(s,s+d); FOR(i,1,d-1) s[i].e2=min(s[i].e2,s[i-1].e2); int ans=inf; FOR(i,pocz[pkrazek],min(m,kon[pkrazek])) { int ct=lower_bound(s,s+d,mp(DiscDiameter(i),0))-s; if (ct==0) continue; int poziom=s[ct-1].e2-m+i-1; if (poziom<ans) ans=poziom; } if (ans<0) ans=0; PutInt(0,ans); Send(0); } } } |