matrix_world_final_2013

 A http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98960#problem/A

题意:给一个正方形,四边上有A-Z带+-,如果是00就不能连任何的。如果两个正方形的边字母相同,正负号相反,就可以连起来。问给输入的n种,每种无限个,可否构成无限大的平面。给的正方形可以旋转或者对称的翻转。

解法:想要无限大,就想能否有几个正方形够成环了,构成环就可以无限延伸。如何判环可以拓扑排序,或者tarjan缩点。关键在建图。对于每个正方形,其中一条边的假设是A+,那么A-就可以通像这个正方形的另外3个符号。建一条有向边。

  1 //#define debug
  2 //#define txtout
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<cctype>
  8 #include<ctime>
  9 #include<iostream>
 10 #include<algorithm>
 11 #include<vector>
 12 #include<queue>
 13 #include<stack>
 14 #include<map>
 15 #include<set>
 16 #define mt(a,b) memset(a,b,sizeof(a))
 17 using namespace std;
 18 typedef long long LL;
 19 const double eps=1e-8;
 20 const double pi=acos(-1.0);
 21 const int inf=0x3f3f3f3f;
 22 const int M=4e4+10;
 23 char a[M][16];
 24 char str[2][16]= {"bounded","unbounded"};
 25 int n;
 26 vector<int> id;
 27 class Toposort { ///拓扑排序(矩阵) O(V^2)
 28     static const int MV=1e2+10;///点的个数
 29     bool mat[MV][MV];
 30     int n,ret[MV],d[MV],i,j,k;
 31 public:
 32     void init(int tn) { ///传入点数,点下标0 开始
 33         n=tn;
 34         for(i=0; i<n; i++)
 35             for(j=0; j<n; j++)
 36                 mat[i][j]=false;
 37     }
 38     void add(int u,int v) {
 39         mat[u][v]=true;
 40     }
 41     bool solve() { ///无法完成排序,返回flase
 42         for(i=0; i<n; i++) {
 43             d[i]=0;
 44             for(j=0; j<n; j++) {
 45                 d[i]+=mat[j][i];
 46             }
 47         }
 48         for(k=0; k<n; k++) {
 49             for(i=0; i<n; i++) {
 50                 if(!d[i]) break;
 51             }
 52             if(i==n) return false;
 53             d[i]=-1;
 54             for(j=0; j<n; j++) {
 55                 d[j]-=mat[i][j];
 56             }
 57             ret[k]=i;
 58         }
 59         return true;
 60     }
 61     int getvalue(int id) { ///0~n-1 中存着字典序最小的序列
 62         return ret[id];
 63     }
 64 } gx;
 65 int get_id(char a,char b){
 66     int result=a-'A';
 67     if(b=='-') result+=26;
 68     return result;
 69 }
 70 int get_other(int a){
 71     if(a<26) return a+26; return a-26;
 72 }
 73 int solve() {
 74     gx.init(52);
 75     for(int i=0; i<n; i++) {
 76         id.clear();
 77         for(int j=0;j<8;j+=2){
 78             if(a[i][j]=='0') continue;
 79             id.push_back(get_id(a[i][j],a[i][j+1]));
 80         }
 81         int len=id.size();
 82         for(int j=0;j<len;j++){
 83             for(int k=j+1;k<len;k++){
 84                 gx.add(get_other(id[j]),id[k]);
 85                 gx.add(get_other(id[k]),id[j]);
 86             }
 87         }
 88     }
 89     return !gx.solve();
 90 }
 91 int main() {
 92 #ifdef txtout
 93     freopen("in.txt","r",stdin);
 94     freopen("out.txt","w",stdout);
 95 #endif
 96     while(~scanf("%d",&n)) {
 97         for(int i=0; i<n; i++) {
 98             scanf("%s",a[i]);
 99         }
100         puts(str[solve()]);
101     }
102     return 0;
103 }
View Code

 发现缩点模板没法判自环。

  1 //#define debug
  2 //#define txtout
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<cctype>
  8 #include<ctime>
  9 #include<iostream>
 10 #include<algorithm>
 11 #include<vector>
 12 #include<queue>
 13 #include<stack>
 14 #include<map>
 15 #include<set>
 16 #define mt(a,b) memset(a,b,sizeof(a))
 17 using namespace std;
 18 typedef long long LL;
 19 const double eps=1e-8;
 20 const double pi=acos(-1.0);
 21 const int inf=0x3f3f3f3f;
 22 const int M=4e4+10;
 23 char a[M][16];
 24 char str[2][16]= {"bounded","unbounded"};
 25 int n;
 26 vector<int> id;
 27 bool mat[64][64];
 28 class Tarjan { ///有向图强连通分量缩点O(V+E)
 29     static const int ME=1e4+10; ///边的个数
 30     static const int MV=1e2+10; ///点的个数
 31     int n,Index,Bcnt,num[MV],belong[MV],dfn[MV],low[MV];
 32     bool instack[MV];
 33     stack<int> s;
 34     void tarjan(int u) {
 35         dfn[u]=low[u]=++Index;
 36         instack[u]=true;
 37         s.push(u);
 38         int v;
 39         for(int i=g.head[u]; ~i; i=g.e[i].next) {
 40             v=g.e[i].v;
 41             if(!dfn[v]) {
 42                 tarjan(v);
 43                 low[u]=min(low[u],low[v]);
 44                 continue;
 45             }
 46             if(instack[v]) {
 47                 low[u]=min(low[u],dfn[v]);
 48             }
 49         }
 50         if(dfn[u]!=low[u]) return ;
 51         Bcnt++;
 52         do {
 53             v=s.top();
 54             s.pop();
 55             instack[v]=false;
 56             belong[v]=Bcnt;
 57             num[Bcnt]++;
 58         } while(u!=v);
 59     }
 60     struct G {
 61         struct E {
 62             int v,next;
 63         } e[ME];
 64         int le,head[MV];
 65         void init(int n) {
 66             le=0;
 67             for(int i=0; i<=n; i++) head[i]=-1;
 68         }
 69         void add(int u,int v) {
 70             e[le].v=v;
 71             e[le].next=head[u];
 72             head[u]=le++;
 73         }
 74     } g;
 75 public:
 76     void init(int tn) { ///传入点数,点下标1 开始
 77         n=tn;
 78         g.init(n);
 79     }
 80     void add(int u,int v) {
 81         g.add(u,v);
 82     }
 83     void solve() {
 84         Index=Bcnt=0;
 85         for(int i=1; i<=n; i++) {
 86             num[i]=dfn[i]=low[i]=instack[i]=0;
 87         }
 88         while(!s.empty()) s.pop();
 89         for(int i=1; i<=n; i++) {
 90             if(!dfn[i]) {
 91                 tarjan(i);
 92             }
 93         }
 94     }
 95     int getbcnt() { ///强连通分量的个数
 96         return Bcnt;
 97     }
 98     int getbelong(int id) { ///属于哪个分量,分量下标1 开始
 99         return belong[id];
100     }
101     int getnum(int id) { ///某个分量的点的个数
102         return num[id];
103     }
104 } gx;
105 int get_id(char a,char b) {
106     int result=a-'A';
107     if(b=='-') result+=26;
108     return result;
109 }
110 int get_other(int a) {
111     if(a<26) return a+26;
112     return a-26;
113 }
114 int solve() {
115     mt(mat,0);
116     for(int i=0; i<n; i++) {
117         id.clear();
118         for(int j=0; j<8; j+=2) {
119             if(a[i][j]=='0') continue;
120             id.push_back(get_id(a[i][j],a[i][j+1]));
121         }
122         int len=id.size();
123         for(int j=0; j<len; j++) {
124             for(int k=j+1; k<len; k++) {
125                 mat[get_other(id[j])][id[k]]=true;
126                 mat[get_other(id[k])][id[j]]=true;
127             }
128         }
129     }
130     gx.init(52);
131     for(int i=0;i<52;i++){
132         for(int j=0;j<52;j++){
133             if(!mat[i][j]) continue;
134             if(i==j) return 1;
135             gx.add(i+1,j+1);
136         }
137     }
138     gx.solve();
139     return gx.getbcnt()!=52;
140 }
141 int main() {
142 #ifdef txtout
143     freopen("in.txt","r",stdin);
144     freopen("out.txt","w",stdout);
145 #endif
146     while(~scanf("%d",&n)) {
147         for(int i=0; i<n; i++) {
148             scanf("%s",a[i]);
149         }
150         puts(str[solve()]);
151     }
152     return 0;
153 }
View Code

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98960#problem/F

题意:有n台机器,每个机器由两个部分组成,每个部分需要k个电池,输入n,k,和2*n*k个电池的值。求如何分配电池,使得每个机器的差值d中最大的最小。差值d等于机器两部分电池的最小值之差。

解法:先把电池按照值小到大排序,二分答案d,判断是否可以满足,如果可以满足,则找更小的,如果不可以则找更大的,就能找到最小的d。判断满足即判断所有的机器差值都小于等于二分的差值即可。从小到大选择,如果相邻的两个差值满足,则直接将这两个座位一个机器的两部分,如果不满足,就将小的扔到之前已经满足的部分的后面。

 1 //#define debug
 2 //#define txtout
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<queue>
13 #include<stack>
14 #include<map>
15 #include<set>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double eps=1e-8;
20 const double pi=acos(-1.0);
21 const int inf=0x3f3f3f3f;
22 const int M=1e6+10;
23 int a[M];
24 int n,k,m;
25 bool judge(int mid){
26     int save=0,sum=0;
27     for(int i=0;i+1<m;i++){
28         if(a[i+1]-a[i]>mid){
29             if(save==0) return false;
30             save--;
31         }
32         else{
33             save+=2*k-2;
34             sum++;
35             if(sum==n) return true;
36             i++;
37         }
38     }
39     return false;
40 }
41 int solve(){
42     sort(a,a+m);
43     int L=0,R=a[m-1]-a[0],result=R;
44     while(L<=R){
45         int mid=(L+R)>>1;
46         if(judge(mid)){
47             result=mid;
48             R=mid-1;
49         }
50         else{
51             L=mid+1;
52         }
53     }
54     return result;
55 }
56 int main(){
57     #ifdef txtout
58     freopen("in.txt","r",stdin);
59     freopen("out.txt","w",stdout);
60     #endif
61     while(~scanf("%d%d",&n,&k)){
62         m=2*n*k;
63         for(int i=0;i<m;i++){
64             scanf("%d",&a[i]);
65         }
66         printf("%d
",solve());
67     }
68     return 0;
69 }
View Code

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98960#problem/J

题意:圆与多边形的交

解法:不会,模板

  1 //#define debug
  2 //#define txtout
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<cctype>
  8 #include<ctime>
  9 #include<iostream>
 10 #include<algorithm>
 11 #include<vector>
 12 #include<queue>
 13 #include<stack>
 14 #include<map>
 15 #include<set>
 16 #define mt(a,b) memset(a,b,sizeof(a))
 17 using namespace std;
 18 typedef long long LL;
 19 const double eps=1e-8;
 20 const double pi=acos(-1.0);
 21 const int inf=0x3f3f3f3f;
 22 const int M=1e2+10;
 23 struct point {
 24     double x,y;
 25 } p[M];
 26 double r;
 27 int n;
 28 class Area_of_circle_polygon {
 29     double xmult(point p1,point p2,point p0) { ///计算向量叉积(P1-P0)x(P2-P0)
 30         return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
 31     }
 32     double Square(double x) { ///平方
 33         return x*x;
 34     }
 35     double Distance(point a,point b) { ///平面两点距离
 36         return sqrt(Square(a.x-b.x)+Square(a.y-b.y));
 37     }
 38     double dmult(point p1,point p2,point p0) {
 39         return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
 40     }
 41     double help_cal(point a,point b,point c,double r,double C){
 42         double d=dmult(a,c,b);
 43         double x=xmult(a,c,b);
 44         return (d+sqrt(r*r*C*C-x*x))/C;
 45     }
 46     double help_again(double tS,double x,double C,double r,double B){
 47         return asin(tS*(1-x/C)*2/r/B)*r*r*0.5+tS*x/C;
 48     }
 49     double cal_area(point a,point b,point c,double r) {
 50         double A,B,C,x,y,tS;
 51         A=Distance(b,c);
 52         B=Distance(a,c);
 53         C=Distance(b,a);
 54         tS=xmult(a,b,c)*0.5;
 55         if(A<r&&B<r) return tS;
 56         if(A<r&&B>=r) {
 57             x=help_cal(a,b,c,r,C);
 58             return help_again(tS,x,C,r,B);
 59         }
 60         if(A>=r&&B<r) {
 61             y=help_cal(b,a,c,r,C);
 62             return help_again(tS,y,C,r,A);
 63         }
 64         if(fabs(xmult(a,b,c))>=r*C||dmult(b,c,a)<=0||dmult(a,c,b)<=0) {
 65             double x=xmult(a,b,c);
 66             double tmp=-asin(x/A/B);
 67             if(dmult(a,b,c)<0){
 68                 if(x<0){
 69                     tmp-=pi;
 70                 }
 71                 else{
 72                     tmp+=pi;
 73                 }
 74             }
 75             else{
 76                 tmp=-tmp;
 77             }
 78             return tmp*r*r*0.5;
 79         }
 80         x=help_cal(a,b,c,r,C);
 81         y=help_cal(b,a,c,r,C);
 82         double t1=help_again(tS,x,C,r,B);
 83         double t2=help_again(tS,y,C,r,A);
 84         return t1+t2-tS;
 85     }
 86 public:
 87     double solve(point p[],int n,point circle,double r) {///传入多边形点数组,点个数,圆心,半径
 88         double area=0;
 89         for(int i=0; i<n; i++) {
 90             area+=cal_area(p[i], p[(i+1)%n], circle, r);
 91         }
 92         return area;
 93     }
 94 } gx;
 95 
 96 int main() {
 97 #ifdef txtout
 98     freopen("in.txt","r",stdin);
 99     freopen("out.txt","w",stdout);
100 #endif
101     point c;
102     c.x=c.y=0;
103     while(~scanf("%d%lf",&n,&r)) {
104         for(int i=0; i<n; i++) {
105             scanf("%lf%lf",&p[i].x,&p[i].y);
106         }
107         printf("%.9f
",gx.solve(p,n,c,r));
108     }
109     return 0;
110 }
View Code

end

原文地址:https://www.cnblogs.com/gaolzzxin/p/4950783.html