Line of Sight
看的题解。大概就是要相互看见,充要条件是在圆上的可视区域有公共点。于是就变成了一个求相交区间个数的题,排序。
没想出来大概是因为思考的时候一直局限于拿切线去扫,没有仔细考虑可视的性质。
Debug了一会,一个小bug是eps开太小了。
1 //============================================================================ 2 // Name : co13nov_sight.cpp 3 // Author : cad 4 // Version : 5 // Copyright : Your copyright notice 6 // Description : Hello World in C++, Ansi-style 7 //============================================================================ 8 #include <cstdio> 9 #include <algorithm> 10 #include <iostream> 11 #include <cmath> 12 13 using namespace std; 14 #define rep(i,n) for (int n__=n,i=1;i<=n__;i++) 15 #define repb(i,b,n) for (int n__=n,i=b;i<=n__;i++) 16 typedef double db; 17 18 const db pi=acos(0)*2,eps=1e-10; 19 const int mN=50000+10; 20 struct ope 21 { 22 int fg; 23 db x; 24 } a[mN*4]; 25 int ta=0; 26 bool operator<(const ope& a,const ope& b) 27 { 28 if (a.fg!=b.fg && fabs(a.x-b.x)<eps) 29 { 30 return a.fg<b.fg; 31 } 32 else 33 return a.x<b.x; 34 } 35 36 void add(db l,db r) 37 { 38 a[++ta].fg=0; 39 a[ta].x=l; 40 a[++ta].fg=1; 41 a[ta].x=r; 42 } 43 int main() 44 { 45 freopen("sight.in","r",stdin); 46 freopen("sight.out","w",stdout); 47 int n; 48 db R; 49 cin>>n>>R; 50 int over=0; 51 rep(i,n) 52 { 53 db x,y; 54 cin>>x>>y; 55 db al=atan2(y,x);//to calc 56 if (al<0) 57 al+=2*pi; 58 db bt=acos(R/sqrt(x*x+y*y));//to calc 59 if (al+bt+eps>2*pi) 60 { 61 add(0,al+bt-2*pi); 62 add(al-bt,2*pi); 63 over++; 64 } 65 else if (al-bt<eps) 66 { 67 add(0,al+bt); 68 add(al-bt+2*pi,2*pi); 69 over++; 70 } 71 else 72 { 73 add(al-bt,al+bt); 74 } 75 } 76 sort(a+1,a+1+ta); 77 long long ans=0; 78 rep(i,ta) 79 { 80 static int now=0; 81 if (a[i].fg==0) 82 { 83 ans+=now; 84 now++; 85 } 86 else 87 { 88 now--; 89 } 90 } 91 ans-=(long long)over*(over-1)/2; 92 cout<<ans<<endl; 93 // cout<<ta<<endl; 94 return 0; 95 }
下面是别人家的写法,,,
for(int iters = 0; iters < 2; iters++) { for(int i = 0; i < N; i++) { /* Move the tangent forward to A[i].first and remove everything no longer * visible. */ while(!q.empty() && q.top() < A[i].first) { q.pop(); } if(iters == 1) { /* We iterate around the points twice but only count points added the * second iteration to ensure the sweep tangent contains what it * should. */ result += q.size(); } q.push(A[i].second); A[i].first += 2 * PI; A[i].second += 2 * PI; } }
下一题
USACO 2013 November Contest, Gold
Problem 3. No Change
这题看懂题意就很水了,货物序列的顺序不变。。。
一个很简单的状态压缩就可以了。。。
1 //============================================================================ 2 // Name : co13nov_sight.cpp 3 // Author : cad 4 // Version : 5 // Copyright : Your copyright notice 6 // Description : Hello World in C++, Ansi-style 7 //============================================================================ 8 #include <cstdio> 9 #include <algorithm> 10 #include <iostream> 11 #include <cstring> 12 #include <cmath> 13 14 using namespace std; 15 #define rep(i,n) for (int n__=n,i=1;i<=n__;i++) 16 #define repb(i,b,n) for (int n__=n,i=b;i<=n__;i++) 17 typedef double db; 18 const int mC=17,mN=100000+10; 19 int c[mC],opti[mC]; 20 int f[1<<mC]; 21 int s[mN],w[mN]; 22 int bisc(int v,int l,int r) 23 { 24 int mid; 25 while (l<r) 26 { 27 mid=(l+r)/2; 28 if (s[mid+1]<=v) 29 l=mid+1; 30 else 31 r=mid; 32 } 33 return l; 34 } 35 int main() 36 { 37 freopen("nochange.in","r",stdin); 38 freopen("nochange.out","w",stdout); 39 int n,k; 40 cin>>k>>n; 41 rep(i,k) 42 cin>>c[i]; 43 s[0]=0; 44 rep(i,n) 45 { 46 cin>>w[i]; 47 s[i]=w[i]+s[i-1]; 48 } 49 50 memset(f,0,sizeof(f)); 51 long long ans=-1; 52 repb(opt,1,(1<<(k))-1) 53 { 54 int bo=opt; 55 rep(i,k) 56 { 57 opti[i]=bo%2; 58 bo/=2; 59 } 60 rep(i,k) 61 if (opti[i]) 62 { 63 int bef=opt ^ (1<<(i-1)); 64 f[opt]=max(f[opt],bisc(s[f[bef]]+c[i],f[bef],n)); 65 } 66 if (f[opt]==n) 67 { 68 long long tot=0; 69 rep(i,k) 70 if (!opti[i]) 71 { 72 tot+=c[i]; 73 } 74 ans=max(ans,tot); 75 } 76 } 77 cout<<ans<<endl; 78 return 0; 79 }
别人家的写法。
1 vector<int> dp(1 << K); 2 int ans = -1; 3 for (int b = 1; b < (1 << K); b++) 4 { 5 int best = 0; 6 int rem = 0; 7 for (int i = 0; i < K; i++) 8 { 9 int m = 1 << i;//用位运算搞,不用开位数组了 10 if (b & m) 11 { 12 int last = acc[dp[b ^ m]]; 13 int trg = upper_bound(acc.begin(), acc.end(), last + coins[i]) 14 - acc.begin() - 1;//用stl,不用自己二分了 15 if (trg > best) 16 best = trg; 17 } 18 else//直接把统计和dp合并了 19 rem += coins[i]; 20 }
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号