hdu 4305 Lightning 高斯消元 计算几何
来源:互联网 发布:金吉数据黑匣子软件 编辑:程序博客网 时间:2024/06/07 15:49
【BestCoder Round #2 来了!】7月27号19:00~21:00(赛前30分钟停止注册比赛)
Lightning
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1432 Accepted Submission(s): 455
Problem Description
There are N robots standing on the ground (Don't know why. Don't know how).
Suddenly the sky turns into gray, and lightning storm comes! Unfortunately, one of the robots is stuck by the lightning!
So it becomes overladen. Once a robot becomes overladen, it will spread lightning to the near one.
The spreading happens when:
Robot A is overladen but robot B not.
The Distance between robot A and robot B is no longer than R.
No other robots stand in a line between them.
In this condition, robot B becomes overladen.
We assume that no two spreading happens at a same time and no two robots stand at a same position.
The problem is: How many kind of lightning shape if all robots is overladen? The answer can be very large so we output the answer modulo 10007. If some of the robots cannot be overladen, just output -1.
Suddenly the sky turns into gray, and lightning storm comes! Unfortunately, one of the robots is stuck by the lightning!
So it becomes overladen. Once a robot becomes overladen, it will spread lightning to the near one.
The spreading happens when:
Robot A is overladen but robot B not.
The Distance between robot A and robot B is no longer than R.
No other robots stand in a line between them.
In this condition, robot B becomes overladen.
We assume that no two spreading happens at a same time and no two robots stand at a same position.
The problem is: How many kind of lightning shape if all robots is overladen? The answer can be very large so we output the answer modulo 10007. If some of the robots cannot be overladen, just output -1.
Input
There are several cases.
The first line is an integer T (T < = 20), indicate the test cases.
For each case, the first line contains integer N ( 1 < = N < = 300 ) and R ( 0 < = R < = 20000 ), indicate there stand N robots; following N lines, each contains two integers ( x, y ) ( -10000 < = x, y < = 10000 ), indicate the position of the robot.
The first line is an integer T (T < = 20), indicate the test cases.
For each case, the first line contains integer N ( 1 < = N < = 300 ) and R ( 0 < = R < = 20000 ), indicate there stand N robots; following N lines, each contains two integers ( x, y ) ( -10000 < = x, y < = 10000 ), indicate the position of the robot.
Output
One line for each case contains the answer.
Sample Input
33 2-1 00 11 03 2-1 00 01 03 1-1 00 11 0
Sample Output
31-1
这道题题意:
有很多机器人,机器人可能被闪电打中,被电到的机器人可以传导电到半径为R的其他机器人上,但是要求两个机器人之间不能有其他机器人
每次传递,只能由其中一个机器人传递给另一个,任意机器人可以作为起点。
问所有机器人被电到能形成几种图形,
有些机器人不能电到输出-1
解题:
1. 用计算几何处理,把相互可达的点记录下来用假设Dist[i][j]=1 表示i,j可达
dist[i][j] = 0表示i,j不可达,i=j,dist[i][j]=0;
2. 有个生成树计数算法。百度一下,
意思是A[i][j] i!=j A[i][j] =0;
i==j A[i][i]表示与i相连的边数
另D = A-Dist
则D的任意一个n-1阶的行列式就是答案。
高斯消元算行列式
3. 数字可能很大要取模
要计算逆元 求a关于p的逆元
另ax+py=1
x就是a的逆元
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<math.h>using namespace std;#define ll long long#define maxn 307#define mod 10007struct Point{ int x,y; Point (int x=0,int y=0):x(x),y(y){}};int Length(Point a){ return a.x*a.x+a.y*a.y;}Point operator-(Point a,Point b){ return Point(a.x-b.x,a.y-b.y);}int Cross(Point a,Point b){ return a.x*b.y-a.y*b.x;}int Dot(Point a,Point b){ return a.x*b.x+a.y*b.y;}int Onsegment(Point a,Point b,Point c){ if(Cross(a-c,b-c) != 0) return 0; if(Dot(a-b,a-c) < 0) return 1; return 0;}Point point[maxn];int dist[maxn][maxn];void getDist(int n,int r){ memset(dist,0,sizeof(dist)); int flag ; for(int i = 0;i < n; i++){ for(int j = i+1;j < n;j++){ if(Length(point[i]-point[j]) <= r*r){ flag = 0; for(int k = 0;k < n; k++){ if(k == i || k == j) continue; if(Onsegment(point[k],point[i],point[j])){ flag = 1; break; } } if(flag == 0) dist[i][j] = dist[j][i] = 1; } } }}int inv[mod+10];void gcd(int a,int b,int &x,int &y){ if(b == 0 ){ x = 1; y = 0; return ; } gcd(b,a%b,x,y); int y1 = y; y = x-a/b*y; x = y1;}int check[maxn];int dfs(int u){ if(check[u]) return 0; check[u] = 1; int ans = 1; for(int i = 0;i < maxn; i++) if(dist[u][i] == 1) ans+=dfs(i); return ans;}struct Matrix{ int matrix[maxn][maxn]; void init(){ memset(matrix,0,sizeof(matrix)); } int Det(int n, int mod1){ int ans = 1; for(int i = 0;i < n;i++) for(int j = 0;j < n;j++) matrix[i][j] = (matrix[i][j]+mod1)%mod1; for(int i = 0;i < n; i++){ int p=i,x=matrix[i][i]; //寻找列主元 for(int j = i+1;j < n; j++){ if(abs(matrix[j][i]) > abs(x)){ x = matrix[j][i]; p = j; } } for(int j = i;j < n; j++) swap(matrix[p][j],matrix[i][j]); if(p != i) ans = -ans; if(ans < 0) ans+=mod1; if(matrix[i][i] == 0) return -1; ans = ans*matrix[i][i]%mod1; matrix[i][i] %= mod1; if(matrix[i][i] < 0) matrix[i][i]+=mod1; matrix[i][i] = inv[matrix[i][i]]; for(int j = i+1;j < n; j++){ if(matrix[j][i] == 0) continue; matrix[j][i] = (matrix[j][i]*matrix[i][i])%mod1; for(int k = i+1;k<n;k++){ matrix[j][k] = (matrix[j][k]-matrix[i][k]*matrix[j][i])%mod1; if(matrix[j][k] < 0) matrix[j][k]+=mod1; } } } return (ans%mod1+mod1)%mod1; }};int main(){ int n,t,r,x,y; Matrix mat; for(int i = 1;i < mod;i++){ gcd(i,mod,x,y); inv[i] = (x%mod+mod)%mod; } scanf("%d",&t); while(t--){ scanf("%d%d",&n,&r); for(int i = 0;i < n; i++) scanf("%d%d",&point[i].x,&point[i].y); getDist(n,r); memset(check,0,sizeof(check)); if(dfs(0) != n){ printf("-1\n"); continue; } mat.init(); for(int i = 0;i < n; i++) for(int j = 0;j < n; j++){ if(dist[i][j] == 1){ mat.matrix[i][j] = -1; mat.matrix[i][i]++; } } int ans = mat.Det(n-1,mod); printf("%d\n",ans); } return 0;}
0 0
- hdu 4305 Lightning 高斯消元 计算几何
- HDU 4305 Lightning
- HDU 4305 Lightning
- HDU 4305 Lightning
- hdu 3952 计算几何
- HDU 3694计算几何
- hdu 4195#计算几何
- hdu 4353 计算几何
- hdu 3681 计算几何
- hdu 3629 计算几何
- hdu 3629 计算几何
- hdu 5476 (计算几何)
- hdu 2826 计算几何
- hdu 1007(计算几何)
- hdu 1086 计算几何
- hdu 6158 计算几何
- HDU 3952(计算几何)
- hdu - 4305 - Lightning 生成树计数
- Qt linux文件同步写入
- Error:no suitable driver found for jbdc:mysql//localhost:3306/mypano
- 杭电ACM 2012素数判定----20140723
- 1877: [SDOI2009]晨跑 (最小费用最大流)
- C++设置和获取环境变量 .
- hdu 4305 Lightning 高斯消元 计算几何
- 互联网营销
- No result defined for action *Action and result input
- PHP 对 memcache操作类
- LeetCode OJ - Unique Paths II
- HDU4869:Turn the pokers(费马小定理+快速幂)
- 夏令营开始咯
- 使用opencv进行多路视频的播放
- Win32 DLL的一个调试心得