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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
launch
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
数模
!!!
线性基:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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: ", ++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 ", lb.kth(k)); 81 } 82 } 83 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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: ",++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 ",query(k)); 51 } 52 } 53 }
java!!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ", 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 ", ans); 41 } 42 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ",dis[ans]); 70 else puts("No Solution!"); 71 } 72 return 0; 73 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ", 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 ", poly[i].x, poly[i].y); 242 for(int i = 0; i < start; i++) 243 printf("%.4lf %.4lf ", 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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ", ans.a, ans.b); 116 } 117 return 0; 118 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(" "); 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(" "); 197 } 198 return 0; 199 }
.vimrc
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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>
vim github链接