暂存

ubuntu下安装vscode

sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make
sudo apt-get update
sudo apt-get install ubuntu-make
sudo umake web visual-studio-code

配置相关

task

1 {
2     "version": "0.1.0",
3     "command": "g++",
4     "isShellCommand": true,    // 是否为Shell命令
5     "args": ["-std=c++11","-g","${file}","-o","${fileDirname}/${fileBasenameNoExtension}.out"],
6     "showOutput": "always"
7 }
View Code

launch

 1 {
 2     "version": "0.2.0",
 3     "configurations": [
 4         {
 5             "name": "(gdb) Launch",
 6             "type": "cppdbg",
 7             "request": "launch",
 8             "program": "${fileDirname}/${fileBasenameNoExtension}.out",
 9             "args": [],
10             "stopAtEntry": false,
11             "cwd": "${workspaceRoot}",
12             "environment": [],
13             "externalConsole": true,
14             "MIMode": "gdb",
15             "setupCommands": [
16                 {
17                     "description": "Enable pretty-printing for gdb",
18                     "text": "-enable-pretty-printing",
19                     "ignoreFailures": true
20                 }
21             ]
22         }
23     ]
24 }
View Code

 

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int EMPTY = 0x3f3f3f3f;
  4 template<typename T>
  5 class Node{
  6 public:
  7     T leftk, rightk;
  8     Node *left, *right, *center;
  9     Node(){
 10         leftk = rightk = EMPTY;
 11         left = right = center = NULL;
 12     }
 13     ~Node(){}
 14     bool isLeaf(){
 15         return left == NULL;
 16     }
 17 };
 18 template <typename T>
 19 class Tree{
 20 public:
 21     Node<T> *rt;
 22     Tree(){
 23         rt = NULL;
 24     }
 25     bool findhelp(Node<T> *cur, const T &key){
 26         if(cur == NULL) return false;
 27         if(key == cur->leftk) {
 28             //
 29             return true;
 30         }else if(cur->rightk != EMPTY && key == cur->rightk){
 31            //
 32             return true;
 33         }
 34         if(key < cur->leftk){
 35             return findhelp(cur->left, key);
 36         }else if(cur->rightk == EMPTY || key < cur->rightk){
 37             return findhelp(cur->center, key);
 38         }else {
 39             return findhelp(cur->right, key);
 40         }
 41     }
 42     bool inserthelp(Node<T> *&cur, const T &key, T &retval, Node<T> *&retptr){
 43         T myretv;
 44         Node<T> * myretp = NULL;
 45         if(cur == NULL){
 46             //空树
 47             cur = new Node<T>();
 48             cur->leftk = key;
 49         }else if(cur->isLeaf()){
 50             //到达叶子,插入
 51             if(cur->rightk == EMPTY){
 52                 if(cur->leftk < key){
 53                     cur->rightk = key;
 54                 }else{
 55                     cur->rightk = cur->leftk;
 56                     cur->leftk = key;
 57                 }
 58             }else{
 59                 splitnode(cur, key, NULL, retval, retptr);
 60             }
 61         }else if(key < cur->leftk){
 62             inserthelp(cur->left, key, myretv, myretp);
 63         }else if(cur->right == NULL || key < cur->rightk){
 64             inserthelp(cur->center, key, myretv, myretp);
 65         }else inserthelp(cur->right, key, myretv, myretp);
 66         if(myretp != NULL){
 67             if(cur->rightk != EMPTY){
 68                 splitnode(cur, myretv, myretp, retval, retptr);
 69             }else{
 70                 if(myretv < cur->leftk){
 71                     cur->rightk = cur->leftk;
 72                     cur->leftk = myretv;
 73                     cur->right = cur->center;
 74                     cur->center = myretp;
 75                 }else{
 76                     cur->rightk = myretv;
 77                     cur->right = myretp;
 78                 }
 79             }
 80         }
 81         return true;
 82     }
 83 
 84     bool splitnode(Node<T> *cur, const T &inval, Node<T> *inptr, T &retval, Node<T> *&retptr){
 85         if(inval < cur->leftk){
 86             retval = cur->leftk;
 87             cur->leftk = inval;
 88             retptr->leftk = cur->rightk;
 89             retptr->left = cur->center;
 90             retptr->center = cur->right;
 91             cur->center = inptr;
 92         }else if(inval < cur->rightk){
 93             retval = inval;
 94             retptr->leftk = cur->rightk;
 95             retptr->left = inptr;
 96             retptr->center = cur->right;
 97         }else{
 98             retval = cur->rightk;
 99             retptr->leftk = inval;
100             retptr->left = cur->right;
101             retptr->center = inptr;
102         }
103         cur->rightk = EMPTY;
104         return true;
105     }
106     void print(){
107         queue<Node<T> *> q;
108         q.push(rt);
109         while(!q.empty()){
110             Node<T> *temp = q.front();
111             if(temp == NULL) continue;
112             if(temp->leftk != EMPTY){
113                 cout<<temp->leftk<<" ";
114                 q.push(temp->left);
115                 q.push(temp->center);
116             }
117             if(temp->rightk != EMPTY){
118                 cout<<temp->rightk<<" ";
119                 q.push(temp->right);
120             }
121         }
122     }
123 
124 };
125 int main(){
126     int n;
127 
128     while(cin>>n){
129         Tree<int> tree;
130         for(int i = 0; i < n; i++){
131             int x;
132             cin>>x;
133             int temp;
134             Node<int> *rev;
135             tree.inserthelp(tree.rt, x, temp, rev);
136         }
137         tree.print();
138 
139     }
140 }
View Code

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define LL long long
 5 
 6 
 7 
 8 map<string, vector<string>> mp;
 9 
10 int n;
11 
12 bool suff(string &x, string &y) {
13     if(x.length() > y.length()) return 0;
14     int len = y.length();
15     for(int i = 0; i < x.length(); ++i) {
16         if(x[i] != y[len - x.length() + i]) return 0;
17     }
18     return 1;
19 }
20 
21 int main() {
22     cin >> n;
23     for(int i = 1; i <= n; ++i) {
24         string name;
25         cin >> name;
26         int num;
27         cin >> num;
28         for(int j = 1; j <= num; ++j) {
29             string x;
30             cin >> x;
31             mp[name].push_back(x);
32         }
33     }
34     for(auto &it: mp) {
35         vector<string> &vt = it.second;
36         vector<string> tmp;
37         for(int i = 0; i < vt.size(); ++i) {
38             bool flag = 0;
39             for(int j = 0; j < vt.size(); ++j) {
40                 if(i == j) continue;
41                 if(suff(vt[i], vt[j])) {
42                     if(i < j && vt[i] == vt[j]) continue;
43                     flag = 1;
44                     break;
45                 }
46             }
47             if(!flag) tmp.push_back(vt[i]);
48         }
49         vt = tmp;
50     }
51     cout << mp.size() << endl;
52     for(auto& it: mp) {
53         vector<string>& vt = it.second;
54         cout << it.first << ' ';
55         cout << vt.size();
56         for(auto& x: vt) cout << ' ' << x;
57         cout << endl;
58     }
59     return 0;
60 }
View Code

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define LL long long
 5 #define N 200020
 6 
 7 int n;
 8 pair<int, int> a[N];
 9 
10 int main() {
11     scanf("%d", &n);
12     for(int i = 1; i <= n; ++i) {
13         int x;
14         scanf("%d", &x);
15         if(x == 0) a[i] = make_pair(2, 0);
16         else if(x == 1) a[i] = make_pair(1, 0);
17         else {
18             int t = sqrt(x * 1.0);
19             if(t * t == x) a[i] = make_pair(1, 0);
20             else {
21                 int y = min(x - t * t, (t + 1) * (t + 1) - x);
22                 a[i] = make_pair(0, y);
23             }
24         }
25     }
26     sort(a + 1, a + n + 1, [](pair<int, int> &x, pair<int, int>& y) {
27         return x.first - x.second > y.first - y.second;
28          });
29     LL ans = 0;
30     for(int i = 1; i <= n; ++i) {
31         if(i <= n / 2) ans += a[i].second;
32         else ans += a[i].first;
33     }
34     cout << ans << endl;
35     return 0;
36 }
View Code

 

 数模

层次分析法

 

 

!!!

1

2

3

wangluoliu

 

czk

CLJ

hhh

 

线性基:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long 
 4 struct LiBase{
 5     LL a[63],p[63];
 6     int cnt;  // 重建后,该线性基的范围是[1,1<<(cnt)-1]
 7     //初始化
 8     void init(){
 9         cnt=0;
10         memset(a,0,sizeof(a));
11         memset(p,0,sizeof(p));
12     }
13     //插入
14     bool insert(LL x){
15         for(int i=62;i>=0&&x;i--)if(x&(1LL<<i)){
16             if(!a[i]){
17                 a[i]=x;
18                 break;
19             }else x^=a[i];
20         }
21         return x>0;
22     }
23     //重建
24     void rebuild(){
25         for(int i=62;i>=0;i--)
26             for(int j=i-1;j>=0;j--) if(a[j]&(1LL<<i)) a[j]^=a[i];
27         for(int i=0;i<=62;i++) if(a[i]) p[cnt++]=a[i];
28     }
29     //第k小
30     LL kth(LL k){
31         LL ans=0;
32         if(k>=(1LL<<cnt)) return -1;
33         for(int i=cnt-1;i>=0;i--){
34             if(k&(1LL<<i)) ans^=p[i];
35         }
36         return ans;
37     }
38 };
39 
40 void init(){
41     freopen("in.txt", "w", stdout);
42     cout<<10<<endl;
43     for(int i = 0 ; i <10; i++){
44         int n = rand()%13 +1;
45             cout<<n<<endl;
46         for(int j = 1; j <= n; j++){ cout<<rand()%1313+1<<" "  ;
47 if(j%10==0) cout<<endl;}
48         cout<<endl;
49         int q = 3;
50 cout<<3<<endl;
51         for(int j = 0; j < 3; j++) cout<<rand()%13+1<<" ";
52 cout<<endl;
53 }
54     
55 }
56 
57 LiBase lb;
58 int main(){
59     int t, kase = 0;
60     freopen("in.txt", "r", stdin);
61     freopen("out.txt", "w", stdout);
62     scanf("%d", &t);
63     while(t--){
64         lb.init();
65         int n;
66         scanf("%d", &n);    
67         LL x;
68         for(int i = 0 ; i < n; i++){
69             scanf("%lld", &x);
70             lb.insert(x);
71         }
72         lb.rebuild();
73         int q;
74         LL k;
75         printf("Case #%d:\n", ++kase);
76         scanf("%d", &q);
77         for(int i = 0 ; i < q; i++){
78             scanf("%lld", &k);
79             if(lb.cnt != n) k--;
80             printf("%lld\n", lb.kth(k));
81         }
82     }
83 }
bug
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn=1e4+10;
 5 ll bin[maxn],a[maxn],k;
 6 int n;
 7 void init(){
 8     bin[0]=1;
 9     for(int i=1;i<=60;i++) bin[i]=bin[i-1]<<1;
10 }
11 int now;
12 
13 void gauss(int n){
14     now=1;
15     for(int i=60;i>=0;i--){
16         int j=now;
17         while(j<=n&&!(a[j]&bin[i])) j++;
18         if(j==n+1) continue;
19         if(j!=now) swap(a[j],a[now]);
20         for(int k=1;k<=n;k++) if(k!=now){
21             if(a[k]&bin[i]) a[k]^=a[now];
22         }
23         now++;
24     }
25     now--;
26 }
27 ll query(ll k){
28     ll ans=0;
29     if(now!=n) k--;  //now!=n说明n个数线性相关,异或可以为0
30     if(k>=bin[now]) return -1;
31     for(int i=1;i<=now;i++)
32         if(k&bin[now-i]) ans^=a[i];
33     return ans;
34 }
35 int main(){
36 freopen("in.txt", "r", stdin);
37 freopen("out1.txt", "w", stdout);
38     int t,kase=0;
39     scanf("%d",&t);
40     init();
41     while(t--){
42         printf("Case #%d:\n",++kase);
43         scanf("%d",&n);
44         for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
45         gauss(n);
46         int q;
47         scanf("%d",&q);
48         while(q--){
49             scanf("%lld",&k);
50             printf("%lld\n",query(k));
51         }
52     }
53 }
ac

 

 

java!!

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int k, r;
 5 
 6 int main() {
 7         while(scanf("%d %d", &k, &r)!=EOF){
 8         int m = (1<<k) - r;
 9         double ans = 0;
10         int i;
11         for(i = 1; (1<<i)-1 <= m; i++){
12             double p = 1.0;
13            // int a = (1<<k) - (1<<i) + 2 - r;
14             //int c = (1<<k) - r + 1;
15             int a = (1<<k) - 1;
16             int c = (1<<k) - r;
17             for(int j = 0; j <(1<<i)-1 ; j++) {
18                 p = p*c/a;
19                 a--;
20                 c--;
21             }
22             ans += p;
23         }
24         printf("%.20lf\n", ans);
25 
26         ans = 0 ;
27          for(i = 1; (1<<i)-1 <= m; i++){
28             double p = 1.0;
29             int a = (1<<k) - (1<<i) + 2 - r;
30             int c = (1<<k) - r + 1;
31 
32             for(int j = 1; j <r; j++) {
33                 p = p*a/c;
34                 a++;
35                 c++;
36             }
37             ans += p;
38         }
39 
40         printf("%.20lf\n", ans);
41         }
42 }
View Code

 

 1 set nocompatible
 2 source $VIMRUNTIME/vimrc_example.vim
 3 source $VIMRUNTIME/mswin.vim
 4 behave mswin
 5 
 6 set number
 7 set cursorline " 突出显示当前行
 8 set smartindent " 开启新行时使用智能自动缩进
 9 set tabstop=4
10 set diffexpr=MyDiff()
11 colorscheme evening
12 set guioptions-=T " 隐藏工具栏
13 set guioptions-=m " 隐藏菜单栏
14 "set showmatch " 插入括号时,短暂地跳转到匹配的对应括号
15 " set matchtime=2 " 短暂跳转到匹配括号的时间
16 
17 "下面试一下
18 set softtabstop=4
19 set shiftwidth=4
20 " 关闭方向键, 强迫自己用 hjkl
21 map <Left> <Nop>
22 map <Right> <Nop>
23 map <Up> <Nop>
24 map <Down> <Nop>
25 "Treat long lines as break lines (useful when moving around in them)
26 "se swap之后,同物理行上直接跳
27 nnoremap k gk
28 nnoremap gk k
29 nnoremap j gj
30 nnoremap gj j
31 " 在上下移动光标时,光标的上方或下方至少会保留显示的行数
32 set scrolloff=7
33 
34 " Go to home and end using capitalized directions
35 noremap H ^
36 noremap L $
37 
38 
39 autocmd GUIEnter * simalt ~x    "最大化 
40 highlight LineNr guifg=purple
41 highlight LineNr guibg=black
42 "ighlight LineNr ctermfg=white
43 "highlight LineNr ctermbg=black
44 
45 function MyDiff()
46   let opt = '-a --binary '
47   if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
48   if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
49   let arg1 = v:fname_in
50   if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif
51   let arg2 = v:fname_new
52   if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif
53   let arg3 = v:fname_out
54   if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif
55   let eq = ''
56   if $VIMRUNTIME =~ ' '
57     if &sh =~ '\<cmd'
58       let cmd = '""' . $VIMRUNTIME . '\diff"'
59       let eq = '"'
60     else
61       let cmd = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff"'
62     endif
63   else
64     let cmd = $VIMRUNTIME . '\diff'
65   endif
66   silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3 . eq
67 endfunction
View Code

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef int Sta[9];
 5 
 6 const int maxn=1000010;
 7 Sta st[maxn],goal;
 8 int dis[maxn];
 9 
10 int dir[4][2]={-1,0,1,0,0,1,0,-1};
11 
12 const int mod=1313131;                                                                                                                                                                      
13 int head[mod],nex[maxn];
14 
15 void init_vis(){
16     memset(head,0,sizeof(head));
17 }
18 int hs(Sta& s){
19     int v=0;
20     for(int i=0;i<9;i++) v=v*10+s[i];
21     return v%mod;
22 }
23 int try_vis(int s){
24     int u=hs(st[s]);
25     for(int v=head[u];v;v=nex[v]){
26         if(memcpy(st[s],st[v],sizeof(st[s]))==0) return 0;
27     }
28     nex[s]=head[u];
29     head[u]=s;
30     return 1;
31 }
32 
33 int bfs(){
34     init_vis();
35     int front=1,rear=2;
36     dis[front]=0;
37     while(front<rear){
38         Sta& s=st[front];
39         if(memcmp(goal,s,sizeof(s))==0) return front;
40         int z;
41         for(z=0;z<9;z++) if(!s[z]) break;
42         int x=z/3,y=z%3;
43         for(int i=0;i<4;i++){
44             int nx=x+dir[i][0];
45             int ny=y+dir[i][1];
46             int nz=nx*3+ny;
47             if(nx>=0&&nx<3&&ny>=0&&ny<3){
48                 Sta& t=st[rear];
49                 memcpy(&t,&s,sizeof(s));
50                 t[nz]=s[z];
51                 t[z]=s[nz];
52                 dis[rear]=dis[front]+1;
53                 if(try_vis(rear)) rear++;  //未访问过
54             }
55         }
56         front++;
57     }
58     return 0;
59 }
60 
61 int main(){
62     int T;
63     freopen("in.txt","r",stdin);
64     scanf("%d",&T);
65     while(T--){
66         for(int i=0;i<9;i++) scanf("%d",&st[1][i]);
67         for(int i=0;i<9;i++) goal[i]=(i+1)%9;
68         int ans=bfs();
69         if(ans>0) printf("%d\n",dis[ans]);
70         else puts("No Solution!");
71     }
72     return 0;
73 }
八数码

 

  1 // LA3218/UVa1340 Find the Border
  2 // Rujia Liu
  3 // 注意:本题可以直接使用“卷包裹”法求出外轮廓。本程序只是为了演示PSLG的实现
  4 #include<cstdio>
  5 #include<vector>
  6 #include<cmath>
  7 #include<algorithm>
  8 #include<cstring>
  9 #include<cassert>
 10 using namespace std;
 11 
 12 const double eps = 1e-8;
 13 double dcmp(double x) {
 14   if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
 15 }
 16 
 17 struct Point {
 18   double x, y;
 19   Point(double x=0, double y=0):x(x),y(y) { }
 20 };
 21 
 22 typedef Point Vector;
 23 
 24 Vector operator + (Vector A, Vector B) {
 25   return Vector(A.x+B.x, A.y+B.y);
 26 }
 27 
 28 Vector operator - (Point A, Point B) {
 29   return Vector(A.x-B.x, A.y-B.y);
 30 }
 31 
 32 Vector operator * (Vector A, double p) {
 33   return Vector(A.x*p, A.y*p);
 34 }
 35 
 36 // 理论上这个“小于”运算符是错的,因为可能有三个点a, b, c, a和b很接近(即a<b好b<a都不成立),b和c很接近,但a和c不接近
 37 // 所以使用这种“小于”运算符的前提是能排除上述情况
 38 bool operator < (const Point& a, const Point& b) {
 39   return dcmp(a.x - b.x) < 0 || (dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) < 0);
 40 }
 41 
 42 bool operator == (const Point& a, const Point &b) {
 43   return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
 44 }
 45 
 46 double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
 47 double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
 48 double Length(Vector A) { return sqrt(Dot(A, A)); }
 49 
 50 typedef vector<Point> Polygon;
 51 
 52 Point GetLineIntersection(const Point& P, const Vector& v, const Point& Q, const Vector& w) {
 53   Vector u = P-Q;
 54   double t = Cross(w, u) / Cross(v, w);
 55   return P+v*t;
 56 }
 57 
 58 bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2) {
 59   double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
 60   c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
 61   return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
 62 }
 63 
 64 bool OnSegment(Point p, Point a1, Point a2) {
 65   return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
 66 }
 67 
 68 // 多边形的有向面积
 69 double PolygonArea(Polygon poly) {
 70   double area = 0;
 71   int n = poly.size();
 72   for(int i = 1; i < n-1; i++)
 73     area += Cross(poly[i]-poly[0], poly[(i+1)%n]-poly[0]);
 74   return area/2;
 75 }
 76 
 77 struct Edge {
 78   int from, to; // 起点,终点,左边的面编号
 79   double ang;
 80 };
 81 
 82 const int maxn = 10000 + 10; // 最大边数
 83 
 84 // 平面直线图(PSGL)实现
 85 struct PSLG {
 86   int n, m, face_cnt;
 87   double x[maxn], y[maxn];
 88   vector<Edge> edges;
 89   vector<int> G[maxn];
 90   int vis[maxn*2];  // 每条边是否已经访问过
 91   int left[maxn*2]; // 左面的编号
 92   int prev[maxn*2]; // 相同起点的上一条边(即顺时针旋转碰到的下一条边)的编号
 93 
 94   vector<Polygon> faces;
 95   double area[maxn]; // 每个polygon的面积
 96 
 97   void init(int n) {
 98     this->n = n;
 99     for(int i = 0; i < n; i++) G[i].clear();
100     edges.clear();
101     faces.clear();
102   }
103 
104   // 有向线段from->to的极角
105   double getAngle(int from, int to) {
106     return atan2(y[to]-y[from], x[to]-x[from]);
107   }
108 
109   void AddEdge(int from, int to) {
110     edges.push_back((Edge){from, to, getAngle(from, to)});
111     edges.push_back((Edge){to, from, getAngle(to, from)});
112     m = edges.size();
113     G[from].push_back(m-2);
114     G[to].push_back(m-1);
115   }
116 
117   // 找出faces并计算面积
118   void Build() {
119     for(int u = 0; u < n; u++) {
120       // 给从u出发的各条边按极角排序
121       int d = G[u].size();
122       for(int i = 0; i < d; i++)
123         for(int j = i+1; j < d; j++) // 这里偷个懒,假设从每个点出发的线段不会太多
124           if(edges[G[u][i]].ang > edges[G[u][j]].ang) swap(G[u][i], G[u][j]);
125       for(int i = 0; i < d; i++)
126         prev[G[u][(i+1)%d]] = G[u][i];
127     }
128 
129     memset(vis, 0, sizeof(vis));
130     face_cnt = 0;
131     for(int u = 0; u < n; u++)
132       for(int i = 0; i < G[u].size(); i++) {
133         int e = G[u][i];
134         if(!vis[e]) { // 逆时针找圈
135           face_cnt++;
136           Polygon poly;
137           for(;;) {
138             vis[e] = 1; left[e] = face_cnt;
139             int from = edges[e].from;
140             poly.push_back(Point(x[from], y[from]));
141             e = prev[e^1];
142             if(e == G[u][i]) break;
143             assert(vis[e] == 0);
144           }
145           faces.push_back(poly);
146         }
147       }
148 
149     for(int i = 0; i < faces.size(); i++) {
150       area[i] = PolygonArea(faces[i]);
151     }
152   }
153 };
154 
155 PSLG g;
156 
157 const int maxp = 100 + 5;
158 int n, c;
159 Point P[maxp];
160 
161 Point V[maxp*(maxp-1)/2+maxp];
162 
163 // 在V数组里找到点p
164 int ID(Point p) {
165   return lower_bound(V, V+c, p) - V;
166 }
167 
168 //假定poly没有相邻点重合的情况,只需要删除三点共线的情况
169 Polygon simplify(const Polygon& poly) {
170   Polygon ans;
171   int n = poly.size();
172   for(int i = 0; i < n; i++) {
173     Point a = poly[i];
174     Point b = poly[(i+1)%n];
175     Point c = poly[(i+2)%n];
176     if(dcmp(Cross(a-b, c-b)) != 0) ans.push_back(b);
177   }
178   return ans;
179 }
180 
181 void build_graph() {
182   c = n;
183   for(int i = 0; i < n; i++)
184     V[i] = P[i];
185 
186   vector<double> dist[maxp]; // dist[i][j]是第i条线段上的第j个点离起点(P[i])的距离
187   for(int i = 0; i < n; i++)
188     for(int j = i+1; j < n; j++)
189       if(SegmentProperIntersection(P[i], P[(i+1)%n], P[j], P[(j+1)%n])) {
190         Point p = GetLineIntersection(P[i], P[(i+1)%n]-P[i], P[j], P[(j+1)%n]-P[j]);
191         V[c++] = p;
192         dist[i].push_back(Length(p - P[i]));
193         dist[j].push_back(Length(p - P[j]));
194       }
195 
196   // 为了保证“很接近的点”被看作同一个,这里使用了sort+unique的方法
197   // 必须使用前面提到的“理论上是错误”的小于运算符,否则不能保证“很接近的点”在排序后连续排列
198   // 另一个常见的处理方式是把坐标扩大很多倍(比如100000倍),然后四舍五入变成整点(计算完毕后再还原),用少许的精度损失换来鲁棒性和速度。
199   sort(V, V+c);
200   c = unique(V, V+c) - V;
201 
202   g.init(c); // c是平面图的点数
203   for(int i = 0; i < c; i++) {
204     g.x[i] = V[i].x;
205     g.y[i] = V[i].y;
206   }
207   for(int i = 0; i < n; i++) {
208     Vector v = P[(i+1)%n] - P[i];
209     double len = Length(v);
210     dist[i].push_back(0);
211     dist[i].push_back(len);
212     sort(dist[i].begin(), dist[i].end());
213     int sz = dist[i].size();
214     for(int j = 1; j < sz; j++) {
215       Point a = P[i] + v * (dist[i][j-1] / len);
216       Point b = P[i] + v * (dist[i][j] / len);
217       if(a == b) continue;
218       g.AddEdge(ID(a), ID(b));
219     }
220   }
221 
222   g.Build();
223 
224   Polygon poly;
225   for(int i = 0; i < g.faces.size(); i++)
226     if(g.area[i] < 0) { // 对于连通图,惟一一个面积小于零的面是无限面
227       poly = g.faces[i];
228       reverse(poly.begin(), poly.end()); // 对于内部区域来说,无限面多边形的各个顶点是顺时针的
229       poly = simplify(poly); // 无限面多边形上可能会有相邻共线点
230       break;
231     }
232 
233   int m = poly.size();
234   printf("%d\n", m);
235 
236   // 挑选坐标最小的点作为输出的起点
237   int start = 0;
238   for(int i = 0; i < m; i++)
239     if(poly[i] < poly[start]) start = i;
240   for(int i = start; i < m; i++)
241     printf("%.4lf %.4lf\n", poly[i].x, poly[i].y);
242   for(int i = 0; i < start; i++)
243     printf("%.4lf %.4lf\n", poly[i].x, poly[i].y);
244 }
245 
246 int main() {
247   while(scanf("%d", &n) == 1 && n) {
248     for(int i = 0; i < n; i++) {
249       int x, y;
250       scanf("%d%d", &x, &y);
251       P[i] = Point(x, y);
252     }
253     build_graph();
254   }
255   return 0;
256 }
3218

 

  1 // LA4973 Ardenia
  2 // Rujia Liu
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 struct Point3 {
  9   int x, y, z;
 10   Point3(int x=0, int y=0, int z=0):x(x),y(y),z(z) { }
 11 };
 12 
 13 typedef Point3 Vector3;
 14 
 15 Vector3 operator + (const Vector3& A, const Vector3& B) { return Vector3(A.x+B.x, A.y+B.y, A.z+B.z); }
 16 Vector3 operator - (const Point3& A, const Point3& B) { return Vector3(A.x-B.x, A.y-B.y, A.z-B.z); }
 17 Vector3 operator * (const Vector3& A, int p) { return Vector3(A.x*p, A.y*p, A.z*p); }
 18 
 19 bool operator == (const Point3& a, const Point3& b) {
 20   return a.x==b.x && a.y==b.y && a.z==b.z;
 21 }
 22 
 23 Point3 read_point3() {
 24   Point3 p;
 25   scanf("%d%d%d", &p.x, &p.y, &p.z);
 26   return p;
 27 }
 28 
 29 int Dot(const Vector3& A, const Vector3& B) { return A.x*B.x + A.y*B.y + A.z*B.z; }
 30 int Length2(const Vector3& A) { return Dot(A, A); }
 31 Vector3 Cross(const Vector3& A, const Vector3& B) { return Vector3(A.y*B.z - A.z*B.y, A.z*B.x - A.x*B.z, A.x*B.y - A.y*B.x); }
 32 
 33 typedef long long LL;
 34 
 35 LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; }
 36 LL lcm(LL a, LL b) { return a / gcd(a,b) * b; }
 37 
 38 struct Rat {
 39   LL a, b;
 40   Rat(LL a=0):a(a),b(1) { }
 41   Rat(LL x, LL y):a(x),b(y) {
 42     if(b < 0) a = -a, b = -b;
 43     LL d = gcd(a, b); if(d < 0) d = -d;
 44     a /= d; b /= d;
 45   }
 46 };
 47 
 48 Rat operator + (const Rat& A, const Rat& B) {
 49   LL x = lcm(A.b, B.b);
 50   return Rat(A.a*(x/A.b)+B.a*(x/B.b), x);
 51 }
 52 
 53 Rat operator - (const Rat& A, const Rat& B) { return A + Rat(-B.a, B.b); }
 54 Rat operator * (const Rat& A, const Rat& B) { return Rat(A.a*B.a, A.b*B.b); }
 55 
 56 void updatemin(Rat& A, const Rat& B) {
 57   if(A.a*B.b > B.a*A.b) A.a = B.a, A.b = B.b;
 58 }
 59 
 60 // 点P到线段AB的距离的平方
 61 Rat Rat_Distance2ToSegment(const Point3& P, const Point3& A, const Point3& B) {
 62   if(A == B) return Length2(P-A);
 63   Vector3 v1 = B - A, v2 = P - A, v3 = P - B;
 64   if(Dot(v1, v2) < 0) return Length2(v2);
 65   else if(Dot(v1, v3) > 0) return Length2(v3);
 66   else return Rat(Length2(Cross(v1, v2)), Length2(v1));
 67 }
 68 
 69 // 求异面直线p1+su和p2+tv的公垂线对应的s。如果平行/重合,返回false
 70 bool Rat_LineDistance3D(const Point3& p1, const Vector3& u, const Point3& p2, const Vector3& v, Rat& s) {
 71   LL b = (LL)Dot(u,u)*Dot(v,v) - (LL)Dot(u,v)*Dot(u,v);
 72   if(b == 0) return false;
 73   LL a = (LL)Dot(u,v)*Dot(v,p1-p2) - (LL)Dot(v,v)*Dot(u,p1-p2);
 74   s = Rat(a, b);
 75   return true;
 76 }
 77 
 78 void Rat_GetPointOnLine(const Point3& A, const Point3& B, const Rat& t, Rat& x, Rat& y, Rat& z) {
 79   x = Rat(A.x) + Rat(B.x-A.x) * t;
 80   y = Rat(A.y) + Rat(B.y-A.y) * t;
 81   z = Rat(A.z) + Rat(B.z-A.z) * t;
 82 }
 83 
 84 Rat Rat_Distance2(const Rat& x1, const Rat& y1, const Rat& z1, const Rat& x2, const Rat& y2, const Rat& z2) {
 85   return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2);
 86 }
 87 
 88 int main() {
 89   int T;
 90   scanf("%d", &T);
 91   LL maxx = 0;
 92   while(T--) {
 93     Point3 A = read_point3();
 94     Point3 B = read_point3();
 95     Point3 C = read_point3();
 96     Point3 D = read_point3();
 97     Rat s, t;
 98     bool ok = false;
 99     Rat ans = Rat(1000000000);
100     if(Rat_LineDistance3D(A, B-A, C, D-C, s))
101       if(s.a > 0 && s.a < s.b && Rat_LineDistance3D(C, D-C, A, B-A, t))
102         if(t.a > 0 && t.a < t.b) {
103           ok = true; // 异面直线/相交直线
104           Rat x1, y1, z1, x2, y2, z2;
105           Rat_GetPointOnLine(A, B, s, x1, y1, z1);
106           Rat_GetPointOnLine(C, D, t, x2, y2, z2);
107           ans = Rat_Distance2(x1, y1, z1, x2, y2, z2);
108         }
109     if(!ok) { // 平行直线/重合直线
110       updatemin(ans, Rat_Distance2ToSegment(A, C, D));
111       updatemin(ans, Rat_Distance2ToSegment(B, C, D));
112       updatemin(ans, Rat_Distance2ToSegment(C, A, B));
113       updatemin(ans, Rat_Distance2ToSegment(D, A, B));
114     }
115     printf("%lld %lld\n", ans.a, ans.b);
116   }
117   return 0;
118 }
LA4937
  1 // UVa12296 Pieces and Discs
  2 // Rujia Liu
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<vector>
  6 #include<algorithm>
  7 
  8 using namespace std;
  9 
 10 const double eps = 1e-8;
 11 double dcmp(double x) {
 12   if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
 13 }
 14 
 15 struct Point {
 16   double x, y;
 17   Point(double x=0, double y=0):x(x),y(y) { }
 18 };
 19 
 20 typedef Point Vector;
 21 
 22 typedef vector<Point> Polygon;
 23 
 24 Vector operator + (Vector A, Vector B) {
 25   return Vector(A.x+B.x, A.y+B.y);
 26 }
 27 
 28 Vector operator - (Point A, Point B) {
 29   return Vector(A.x-B.x, A.y-B.y);
 30 }
 31 
 32 Vector operator * (Vector A, double p) {
 33   return Vector(A.x*p, A.y*p);
 34 }
 35 
 36 double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
 37 double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
 38 double Length2(Vector A) { return Dot(A, A); }
 39 
 40 Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
 41   Vector u = P-Q;
 42   double t = Cross(w, u) / Cross(v, w);
 43   return P+v*t;
 44 }
 45 
 46 bool OnSegment(Point p, Point a1, Point a2) {
 47   return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
 48 }
 49 
 50 // 多边形的有向面积
 51 double PolygonArea(Polygon poly) {
 52   double area = 0;
 53   int n = poly.size();
 54   for(int i = 1; i < n-1; i++)
 55     area += Cross(poly[i]-poly[0], poly[(i+1)%n]-poly[0]);
 56   return area/2;
 57 }
 58 
 59 // cut with directed line A->B, return the left part
 60 // may return a single point or a line segment
 61 Polygon CutPolygon(Polygon poly, Point A, Point B) {
 62   Polygon newpoly;
 63   int n = poly.size();
 64   for(int i = 0; i < n; i++) {
 65     Point C = poly[i];
 66     Point D = poly[(i+1)%n];
 67     if(dcmp(Cross(B-A, C-A)) >= 0) newpoly.push_back(C);
 68     if(dcmp(Cross(B-A, C-D)) != 0) {
 69       Point ip = GetLineIntersection(A, B-A, C, D-C);
 70       if(OnSegment(ip, C, D)) newpoly.push_back(ip);
 71     }
 72   }
 73   return newpoly;
 74 }
 75 
 76 int isPointInPolygon(Point p, Polygon v) {
 77   int wn = 0;
 78   int n = v.size();
 79   for(int i = 0; i < n; i++){
 80     if(OnSegment(p, v[i], v[(i+1)%n])) return -1; // 在边界上
 81     int k = dcmp(Cross(v[(i+1)%n]-v[i], p-v[i]));
 82     int d1 = dcmp(v[i].y - p.y);
 83     int d2 = dcmp(v[(i+1)%n].y - p.y);
 84     if(k > 0 && d1 <= 0 && d2 > 0) wn++;
 85     if(k < 0 && d2 <= 0 && d1 > 0) wn--;
 86   }
 87   if (wn != 0) return 1; // 内部
 88   return 0; // 外部
 89 }
 90 
 91 // 点在圆心内。圆周上不算
 92 bool isInCircle(Point p, Point center, double R) {
 93   return dcmp(Length2(p-center) - R*R) < 0;
 94 }
 95 
 96 // 直线AB和圆心为C,半径为r的圆的交点
 97 // 返回交点个数,t1, t2分别为两个交点在直线方程中的参数,p1和p2为交点本身
 98 int getLineCircleIntersection(Point A, Point B, Point C, double r, double& t1, double& t2){
 99   // 初始方程:(A.x + t(B.x - A.x) - C.x)^2 + (A.y + t(B.y - A.y) - C.y)^2 = r^2
100   // 整理得:(at + b)^2 + (ct + d)^2 = r^2
101   double a = B.x - A.x;
102   double b = A.x - C.x;
103   double c = B.y - A.y;
104   double d = A.y - C.y;
105   // 展开得:(a^2 + c^2)t^2 + 2(ab + cd)t + b^2 + d^2 - r^2 = 0,即et^2 + ft + g = 0
106   double e = a * a + c * c;
107   double f = 2 * (a * b + c * d);
108   double g = b * b + d * d - r * r;
109   double delta = f * f - 4 * e * g; // 判别式
110   if(dcmp(delta) < 0) return 0; // 相离
111   if(dcmp(delta) == 0){ // 相切
112     t1 = t2 = -f / (2 * e);
113     return 1;
114   }
115   t1 = (-f - sqrt(delta)) / (2 * e);
116   t2 = (-f + sqrt(delta)) / (2 * e);
117   return 2;
118 }
119 
120 // 圆和线段是否相交(相切不算)。线段不考虑端点
121 bool CircleIntersectSegment(Point A, Point B, Point p, double R) {
122   double t1, t2;
123   int c = getLineCircleIntersection(A, B, p, R, t1, t2);
124   if(c <= 1) return false;
125   if(dcmp(t1) > 0 && dcmp(t1-1) < 0) return true; // 端点在圆上
126   if(dcmp(t2) > 0 && dcmp(t2-1) < 0) return true;
127   return false;
128 }
129 
130 /////////// 题目相关
131 vector<Polygon> pieces, new_pieces;
132 
133 void cut(int x1, int y1, int x2, int y2) {
134   new_pieces.clear();
135   for(int i = 0; i < pieces.size(); i++) {
136     Polygon left = CutPolygon(pieces[i], Point(x1, y1), Point(x2, y2));
137     Polygon right = CutPolygon(pieces[i], Point(x2, y2), Point(x1, y1));
138     if(left.size() >= 3) new_pieces.push_back(left);
139     if(right.size() >= 3) new_pieces.push_back(right);
140   }
141   pieces = new_pieces;
142 }
143 
144 bool DiscIntersectPolygon(Polygon poly, Point p, double R) {
145   if(isPointInPolygon(p, poly) != 0) return true;
146   if(isInCircle(poly[0], p, R)) return true;
147   int n = poly.size();
148   for(int i = 0; i < n; i++) {
149     if(CircleIntersectSegment(poly[i], poly[(i+1)%n], p, R)) {
150       return true; // 不考虑线段端点
151     }
152     if(isInCircle((poly[i]+poly[(i+1)%n])*0.5, p, R)) {
153       return true; // 两个端点都在圆上
154     }
155   }
156   return false;
157 }
158 
159 void query(Point p, int R) {
160   vector<double> ans;
161   for(int i = 0; i < pieces.size(); i++) {
162     if(DiscIntersectPolygon(pieces[i], p, R)) {
163       ans.push_back(fabs(PolygonArea(pieces[i])));
164     }
165   }
166   printf("%d", ans.size());
167   sort(ans.begin(), ans.end());
168   for(int i = 0; i < ans.size(); i++)
169     printf(" %.2lf", ans[i]);
170   printf("\n");
171 }
172 
173 int main() {
174   int n, m, L, W;
175   while(scanf("%d%d%d%d", &n, &m, &L, &W) == 4 && n) {
176     pieces.clear();
177 
178     Polygon bbox;
179     bbox.push_back(Point(0, 0));
180     bbox.push_back(Point(L, 0));
181     bbox.push_back(Point(L, W));
182     bbox.push_back(Point(0, W));
183     pieces.push_back(bbox);
184 
185     for(int i = 0; i < n; i++) {
186       int x1, y1, x2, y2;
187       scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
188       cut(x1, y1, x2, y2);
189     }
190 
191     for(int i = 0; i < m; i++) {
192       int x, y, R;
193       scanf("%d%d%d", &x, &y, &R);
194       query(Point(x, y), R);
195     }
196     printf("\n");
197   }  
198   return 0;
199 }
12296

 

.vimrc

 1 set tabstop=4
 2 set shiftwidth=4
 3 set showcmd
 4 set number
 5 set ruler
 6 set mouse=a
 7 set autoindent
 8 filetype plugin indent on
 9 map <F5> :w<CR> :!gdb %< -q <CR>
10 map <F7> :w<CR> :!g++ % -o %< -g -Wall<CR>
11 map <F9> :w<CR> :!time ./%< <CR>
ubuntu
 1 syntax on
 2 
 3 set bs=indent,eol,start
 4 set nocp
 5 set nu
 6 set ai
 7 set ts=4
 8 set sw=4
 9 set nobk
10 set ar
11 set acd
12 
13 map <F5> :w<CR> :!gdb %< -q <CR>
14 map <F7> :w<CR> :!g++ % -o %< -g -Wall<CR>
15 map <F9> :w<CR> :!%< <CR>
Windows

 

vim github链接

posted @ 2017-03-31 22:08  yijiull  阅读(617)  评论(0编辑  收藏  举报