0%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <vector>
using namespace std;

const int INF = ~0u>>1;
typedef pair <int,int> P;
#define MID(x,y) ((x+y)>>1)
#define iabs(x) ((x)>0?(x):-(x))
#define REP(i,a,b) for(int i=(a);i<(b);i++)
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
#define mp make_pair
#define print() cout<<"--------"<<endl
#define maxn 110

int x[maxn],y[maxn];
int g[maxn][maxn];
bool vis[maxn];
int zero,n,m,k,nx,ny;
map <string, int> mp1; // 用来保存用户名
map <string, int> mp2; // 用来记录代号
char str[100][100];
string str2[100];
set< int >cur; // set 的插入与消去,好好用,第一次实用
pair< string, int >pair1[100]; // 20-21 解的保存,pair的第一次实用
int os[100];
bool path(int u){
for (int v = 1; v <= ny; v ++){
if (g[u][v] && !vis[v]){
vis[v] = 1;
if (y[v] == -1 || path(y[v])){
x[u] = v;
y[v] = u;
return true;
}
}
}
return false;
}

int MaxMatch(){
int ans = 0;
//if (zero == k) {puts("0");return;}
memset(x, -1, sizeof(x));
memset(y, -1, sizeof(y));
for (int i = 1; i <= nx; i ++){
if (x[i] == -1){
memset(vis, 0, sizeof(vis));
if (path(i)){
ans ++;
}
}
}
return ans;
}

int main(){
int n;

cin >> n;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++) g[i][j] = 1;
for (int i = 1; i <= n; i ++){
scanf("%s",str[i]);
mp1[str[i]] = i;
}

int cnt = 0;
char sign[10],name[100];
while (scanf("%s",sign) && sign[0] != &#39;Q&#39;){
scanf("%s", name);
if (sign[0] == &#39;E&#39;){

if (mp2[name] == 0){
mp2[name] = ++cnt;
str2[cnt] = name;
}
int y = mp2[name];
cur.insert(y);
}else if (sign[0] == &#39;L&#39;){
int y = mp2[name];
cur.erase(y);
}else {
int x = mp1[name];

for (int i = 1; i <= n; i ++){
if (cur.find(i) == cur.end()){
g[x][i] = 0;
}
}

}
}
nx = ny = n;

int mat = MaxMatch();
//cout << mat << endl;
for (int i = 1; i <= n; i ++){
pair1[i] = mp(str2[i],i);
os[i] = 0;
for (int j = 1; j <= n; j ++){
if (g[j][i]){
g[j][i] = 0;
int tmp = MaxMatch();
//cout << tmp << endl;
if (tmp != mat){
os[i] = j;
}
g[j][i] = 1;
}
}
}
sort( pair1 + 1, pair1 + n +1 ); // 对解的排序
int i, j;
for( i = 1; i <= n; i++ )
{
cout<< pair1[i].first << ":";
if( os[pair1[i].second] == 0 )
cout<< "???" << endl;
else
cout<< str[os[pair1[i].second]] << endl;
}
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <cstdio>
# include <cmath>
# include <algorithm>
using namespace std;
#define MAXN 50010
const double EPS = 1e-8;
const double PI = acos(-1.0);
const double pi = 3.14159265359;

typedef struct Point {
double x, y;
Point(double x = 0, double y = 0): x(x), y(y) {}
} Vector;
Vector operator + (Vector a, Vector b) {
return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b) {
return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, double k) {
return Vector(a.x * k, a.y * k);
}
bool operator < (const Point &a, const Point &b) {
return a.y < b.y || (a.y == b.y && a.x < b.x);
}
Point p[MAXN],ch[MAXN];

inline double cross(Vector a, Vector b) {
return a.x * b.y - a.y * b.x;
}
inline double xmult(Point a, Point b, Point c) {
return cross(b - a, c - a);
}

int convex_hull(Point ch[], Point p[], int n)
{
sort(p, p + n);
int ix = 0;
for (int i = 0; i < n; ++i) {
while (ix > 1 && xmult(ch[ix - 2], ch[ix - 1], p[i]) < 0) --ix;
ch[ix++] = p[i];
}
int t = ix;
for (int i = n - 2; i >= 0; --i) {
while (ix > t && xmult(ch[ix - 2], ch[ix - 1], p[i]) < 0) --ix;
ch[ix++] = p[i];
}
return n > 1 ? ix - 1 : ix;
}

int main(int argc, char const *argv[])
{
int n,convexnum;
while (~scanf("%d", &n) && (n != -1)){
for (int i = 0; i < n; i ++){
scanf("%lf%lf", &p[i].x, &p[i].y);
}
convexnum = convex_hull(ch,p,n);
//cout << convexnum << endl;
double ret = 0,tmp;
int p = 1,q = 2;
for (int i = 0; i < convexnum; i ++){
while ((fabs(xmult(ch[i],ch[p + 1],ch[q]))) >
(tmp = fabs(xmult(ch[i],ch[p],ch[q])))){
p = (p + 1) % convexnum;
}
ret = max(ret,tmp);
while ((fabs(xmult(ch[i],ch[p],ch[q + 1]))) >
(tmp = fabs(xmult(ch[i],ch[p],ch[q])))){
q = (q + 1) % convexnum;
}
ret = max(ret,tmp);

}
printf("%.2fn", ret * 0.5);
}
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
# define MAXN 10010
const double EPS = 1e-8;
const double pi = 3.14159265359;
//const double PI = M_PI;
inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
}

typedef struct Point {
double x, y;
Point(double x = 0, double y = 0): x(x), y(y) {}
} Vector;
Vector operator + (Vector a, Vector b) {
return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b) {
return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, double k) {
return Vector(a.x * k, a.y * k);
}
Vector operator / (Vector a, double k) {
return Vector(a.x / k, a.y / k);
}
bool operator == (const Point &a, const Point &b) {
return sgn(a.x - b.x) == 0 && sgn(a.y - b.y) == 0;
}
bool operator < (const Point &a, const Point &b) {
return a.y < b.y || (a.y == b.y && a.x < b.x);
}
inline double dot(Vector a, Vector b) {
return a.x * b.x + a.y * b.y;
}
inline double cross(Vector a, Vector b) {
return a.x * b.y - a.y * b.x;
}
inline double xmult(Point a, Point b, Point c) {
return cross(b - a, c - a);
}
inline double length(Vector a) {
return sqrt(dot(a, a));
}
inline double dis_pp(Point a, Point b) {
return sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
inline double dis_ps(Point p, Point a, Point b) {
Vector v1 = b - a, v2 = p - a, v3 = p - b;
if (a == b) return length(p - a);
if (sgn(dot(v1 , v2)) < 0) return length(v2);
if (sgn(dot(v1 , v3)) > 0) return length(v3);
return fabs(cross(v1 , v2)) / length(v1);
}
inline double dis_pl(Point p, Point a, Point b) {
Vector v1 = b - a, v2 = p - a;
return fabs(cross(v1 , v2)) / length(v1);
}
inline double dis_ss(Point a, Point b, Point c, Point d){
return min(min(dis_ps(c,a,b),dis_ps(d,a,b)),min(dis_ps(a,c,d),dis_ps(b,c,d)));
}
Point p1[MAXN],p2[MAXN],ch1[MAXN],ch2[MAXN];

int convex_hull(Point ch[], Point p[], int n)
{
sort(p, p + n);
int ix = 0;
for (int i = 0; i < n; ++i) {
while (ix > 1 && xmult(ch[ix - 2], ch[ix - 1], p[i]) < 0) --ix;
ch[ix++] = p[i];
}
int t = ix;
for (int i = n - 2; i >= 0; --i) {
while (ix > t && xmult(ch[ix - 2], ch[ix - 1], p[i]) < 0) --ix;
ch[ix++] = p[i];
}
return n > 1 ? ix - 1 : ix;
}

double minimum_distance(Point c1[],int n,Point c2[],int m)
{
int a = 0, b = 0;
for (int i = 0; i < n; i ++)
if (sgn(c1[i].y - c1[a].y) < 0) a = i;
for (int i = 0; i < m; i ++)
if (sgn(c2[i].y - c2[b].y) > 0) b = i;
int p = a, q = b;
double res = dis_pp(c1[p],c2[q]);

do{
int np = (p + 1 == n ? 0 : p + 1), nq = (q + 1 == m ? 0 : q + 1);
int t = sgn(cross(c1[np] - c1[p], c2[q] - c2[nq]));

if (t > 0){//转第一个凸包
res = min(res,dis_ps(c2[q],c1[p],c1[np]));
p = np;
}else if (t < 0){//转第二个凸包
res = min(res,dis_ps(c1[p],c2[q],c2[nq]));
q = nq;
}else {
res = min(res,dis_ss(c1[p],c1[np],c2[q],c2[nq]));
p = np;
q = nq;
}

}while (p != a || q != b);
return res;

}

int main(int argc, char const *argv[])
{
int n,m;
while (~scanf("%d%d", &n, &m) && (n + m)){
for (int i = 0; i < n; i ++){
scanf("%lf%lf", &p1[i].x, &p1[i].y);
}
n = convex_hull(ch1,p1,n);

for (int i = 0; i < m; i ++){
scanf("%lf%lf", &p2[i].x, &p2[i].y);
}

m = convex_hull(ch2,p2,m);
printf("%.5fn",minimum_distance(ch1,n,ch2,m));
}
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <cstdio>
# include <cmath>
# include <algorithm>
using namespace std;
# define MAXN 110
const double EPS = 1e-8;
const double PI = acos(-1.0);
const double pi = 3.14159265359;
typedef struct Point {
double x, y;
Point(double x = 0, double y = 0): x(x), y(y) {}
} Vector;
Point p[MAXN];
struct Circle {
Point c;
double r;
Circle(Point c = Point(), double r = 0): c(c), r(r) {}
};
inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
}

inline double dis_pp(Point a, Point b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

Point circumcenter(Point a, Point b, Point c) {
double x1 = b.x - a.x, y1 = b.y - a.y, e1 = (x1 * x1 + y1 * y1) / 2;
double x2 = c.x - a.x, y2 = c.y - a.y, e2 = (x2 * x2 + y2 * y2) / 2;
double _d = x1 * y2 - x2 * y1;
double _x = a.x + (e1 * y2 - e2 * y1) / _d;
double _y = a.y + (x1 * e2 - x2 * e1) / _d;
return Point(_x, _y);
}

Circle min_circle_cover(Point *p, int n) {
Point c = p[0]; double r = 0;
for ( int i = 1; i < n; ++i) {
if (sgn(dis_pp(c, p[i]) - r) <= 0) continue ;
c = p[i], r = 0;
for ( int j = 0; j < i; ++j) {
if (sgn(dis_pp(c, p[j]) - r) <= 0) continue ;
c.x = (p[i].x + p[j].x) / 2;
c.y = (p[i].y + p[j].y) / 2;
r = dis_pp(c, p[j]);
for ( int k = 0; k < j; ++k) {
if (sgn(dis_pp(c, p[k]) - r) <= 0) continue ;
c = circumcenter(p[i], p[j], p[k]);
r = dis_pp(c, p[k]);
}
}
}
return Circle(c, r);
}

int main(int argc, char const *argv[])
{
int n;Circle c;
while (~scanf("%d", &n) && n){
for (int i = 0; i < n; i ++){
scanf("%lf%lf", &p[i].x, &p[i].y);
}
c = min_circle_cover(p,n);
printf("%.2f %.2f %.2fn", c.c.x,c.c.y,c.r);
}
return 0;
}

最近点对可能在下面三种情况

[l,mid] [mid + 1,r] 以及 mid 的左右 d区域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//hdu1007
//最近点对问题

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define maxn 100100
using namespace std;

struct Point{
double x,y;
}p[maxn];
int num[maxn];
bool cmpx(Point a,Point b){
if (a.x == b.x) return a.y < b.y;
else return a.x < b.x;
}
bool cmpy(int a,int b)//按y递增排序
{
return p[a].y < p[b].y;
}
double dis(int i,int j){
return sqrt((p[i].x - p[j].x) * (p[i].x - p[j].x) +
(p[i].y - p[j].y) * (p[i].y - p[j].y));
}

double find(int l,int r){
if (l + 1 == r) return dis(l,r);
if (l + 2 == r) return min(min(dis(l + 1,r),dis(l,l + 1)),dis(l,r));
int mid = (l + r) / 2;
double ans = min(find(l,mid),find(mid + 1,r));
int cnt = 0;
for (int i = l; i <= r; i ++){
if (fabs(p[i].x - p[mid].x) <= ans)
num[cnt ++] = i;
}
sort(num,num+cnt,cmpy);
for (int i = 0; i < cnt;i ++){
for (int j = i + 1; j < cnt; j ++){
if (fabs(p[num[j]].y - p[num[i]].y) > ans) break;
ans = min(ans,dis(num[i],num[j]));
}
}
return ans;
}

int main(int argc, char const *argv[])
{
int n;
while (~scanf("%d",&n) && n){
for (int i = 0; i < n; i ++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
sort(p,p + n,cmpx);
printf("%.2lfn", find(0,n-1)/2);
}
return 0;
}

尝试了一下Java写SPFA各种不习惯各种蛋疼,不过最终竟然以非常高的时间给过了``貌似是C的N倍了,没做java的IO优化,如果按照petr的那种IO的话应该会快点的

放上代码,觉得写的还不错

先MLE了,由于每次new的时候是new [maxn]这个maxn开的比较大,所以``

然后MLE是由于每个样例都new Graph了,开太多空间了

WA是因为SPFA函数类型是int其实超过int了得用long

RE是因为init的时候head数组初始化是1-M其实应该是1-N``

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.util.*;
import java.io.*;

class Edge{
int v,next,w;
Edge(){};
Edge(int v,int w,int next){
this.v = v;
this.w = w;
this.next = next;
}
}

class Graph{
int N,M;
static int inf = 1000000050;
Edge[] edge;
int num = 0;
int[] Head;
int[] dis;
int[] vis;
Graph(){}
void init(int N,int M){
this.N = N;
this.M = M;
num = 0;
Head = new int[N + 10];
for (int i = 0; i <= N; i ++) Head[i] = -1;
edge = new Edge[M + 10];
dis = new int[N + 10];
vis = new int[N + 10];
}

void addEdge(int u, int v,int w){
edge[num] = new Edge(v,w,Head[u]);
Head[u] = num ++;
}

long SPFA(int st,int ed){
for (int i = 1; i <= N; i ++){
dis[i] = inf; vis[i] = 0;
}
vis[st] = 1;
dis[st] = 0;
//Queue<Integer> queue = new LinkedList<Integer>();
Queue<Integer> Q = new LinkedList<Integer>();
Q.add(st);
while (!Q.isEmpty()){
int u = Q.peek();
Q.remove();
vis[u] = 0;
for (int i = Head[u]; i != -1; i = edge[i].next){
//System.out.println(u + " " + i);
int v = edge[i].v;
if (dis[u] + edge[i].w < dis[v]){
dis[v] = dis[u] + edge[i].w;
if (vis[v] == 0){
vis[v] = 1;
Q.add(v);
}
}
}
}
long sum = 0;
for (int i = st; i <= ed; i ++){
sum += dis[i];
}
return sum;
}

}

public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int T = in.nextInt();
Graph G1 = new Graph();
Graph G2 = new Graph();
while (in.hasNextInt()){
int n = in.nextInt();
int m = in.nextInt();
G1.init(n,m);
G2.init(n,m);
int u,v,w;
for (int i = 0; i < m; i ++){
u = in.nextInt();
v = in.nextInt();
w = in.nextInt();
G1.addEdge(u,v,w);
G2.addEdge(v,u,w);

}

System.out.println(G1.SPFA(1,n) + G2.SPFA(1,n));
}
}
}

这是操作系统课上的作业,SJF的那个调度要计算的实在太多就写了个程序帮我跑了。

题目如下:

**进程 到达时间 执行时间**
**P1 0 10**
** P2 1 8**
** P3 2 2**
** P4 3 4**
** P5 4 8**
**画****Gantt****图说明使用****FCFS****、非抢先式****SJF****、抢先式****SJF****、****RR****(时间片=****3****)调度算法进程调度情况。并分别求四种算法的平均周转时间,平均等待时间。平均权周转时间。**
用程序模拟了下实践过程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int wait[6] = {0};
int p[6] = {0,10,8,2,4,8};
int use[6] = {0};
int arrive[6] = {0,0,1,2,3,4};
int end[6] = {0};
int flag = 1;
for (int t = 0; ; t ++){

//判断进程是否都执行完
for (int cnt = 0,i = 1; i <= 5; i ++){
if (use[i] == p[i]) cnt ++;
if (use[i] == p[i] && end[i] == 0) end[i] = t;
if (cnt == 5) flag = 0;
}
if (!flag) break;

//判定这一秒该分配给哪一个进行调度
//vali表示哪一个进程,val指的最大响应比
int vali;double val = -1;
for (int i = 1; i <= 5; i ++){
if (arrive[i] <= t && use[i] < p[i]){
//算响应比
double tmp = (0.0 + wait[i] + p[i] - use[i]) / (p[i] - use[i]);
//安排调度时先看哪个
//>表示继续做先出现的 >=表示做继续做最后出现的那个进程
if (tmp >= val){
val = tmp;
vali = i;
}
}
}

use[vali] ++;
for (int i = 1; i <= 5; i ++){
if (arrive[i] <= t && use[i] < p[i] && vali != i)
wait[i] ++;
}

cout << "Time:" << t << " P" << vali << endl;
}

for (int i = 1; i <= 5; i ++){
cout << "P" << i << " wait_time: " << wait[i] << endl;
}
for (int i = 1; i <= 5; i ++){
cout << "P" << i << " cycling_time: " << end[i] - arrive[i] << endl;
}
return 0;
}

结果如下,有可能出现两种调度,具体怎样还不清楚是哪种

Time:0 P1 Time:0 P1
Time:1 P1 Time:1 P2
Time:2 P2 Time:2 P1
Time:3 P3 Time:3 P3
Time:4 P3 Time:4 P3
Time:5 P4 Time:5 P4
Time:6 P4 Time:6 P4
Time:7 P4 Time:7 P4
Time:8 P4 Time:8 P4
Time:9 P2 Time:9 P2
Time:10 P2 Time:10 P2
Time:11 P2 Time:11 P2
Time:12 P2 Time:12 P2
Time:13 P2 Time:13 P2
Time:14 P2 Time:14 P2
Time:15 P2 Time:15 P2
Time:16 P1 Time:16 P1
Time:17 P1 Time:17 P1
Time:18 P1 Time:18 P1
Time:19 P1 Time:19 P1
Time:20 P1 Time:20 P1
Time:21 P1 Time:21 P1
Time:22 P1 Time:22 P1
Time:23 P1 Time:23 P1
Time:24 P5 Time:24 P5
Time:25 P5 Time:25 P5
Time:26 P5 Time:26 P5
Time:27 P5 Time:27 P5
Time:28 P5 Time:28 P5
Time:29 P5 Time:29 P5
Time:30 P5 Time:30 P5
Time:31 P5 Time:31 P5
P1 wait_time: 14 P1 wait_time: 14
P2 wait_time: 7 P2 wait_time: 7
P3 wait_time: 1 P3 wait_time: 1
P4 wait_time: 2 P4 wait_time: 2
P5 wait_time: 20 P5 wait_time: 20
P1 cycling_time: 24 P1 cycling_time: 24
P2 cycling_time: 15 P2 cycling_time: 15
P3 cycling_time: 3 P3 cycling_time: 3
P4 cycling_time: 6 P4 cycling_time: 6
P5 cycling_time: 28 P5 cycling_time: 28

数据结构的编程实验,源码如下:

  利用Java的泛型编程,以及链表类全部手动实现
// 循环链表

import java.io.*;
import java.util.*;
@SuppressWarnings("unchecked")
class LinkList>{
    private Node head;
    LinkList(){
        head = null;
    }
    static class Node>{
        T data;
        Node next;
        Node(T data, Node next){//中间节点使用此构造方法
            this.data = data;
            this.next = next;
        }
        Node(T data){ //头尾节点使用此构造方法
            this.data = data; 
            this.next = this;
        }
    } 

    void addHead(T point){ //为链表增加头节点
        head = new Node(point);
    }

    //void addTail(T point){ //为链表增加尾节点
    //    tail = new Node(point);
    //    head.next = tail;
    //}

    void insert(T point){
        if (point.compareTo(head.data) < 0){
            Node newNode = new Node(point,head);
            head = newNode;    
        }else {
            Node preNext = head;
            while (preNext.next != head && 
                    point.compareTo(preNext.next.data) > 0){
                preNext = preNext.next;
            }
            Node newNode = new Node(point,preNext.next);
            preNext.next = newNode;

        }
    }

    void show(){//打印链表
        Node cur = head;
        if (!isEmpty()){
            System.out.print(cur.data + " ");
            cur = cur.next;
            while (cur != head){
                System.out.print(cur.data + " ");
                cur = cur.next;
            }
            System.out.println();
        }else {
            System.out.println("链表错误");
        }
        return ;
    }
    boolean isEmpty(){    //判断链表是否为空  
        if(head != null){    
            return false;    
        }    
        return true;    
    }   

    void delete(T data){   //删除某一节点  
        Node curr = head,prev = head;  
        boolean b = false;
        //System.out.println(head.data);
        if (curr.data.equals(data)){
            while (prev.next != head) prev = prev.next;
            prev.next = head.next;
            head = prev;
            b = true;
            return ;
        }
        curr = head.next;
        while(curr != head){  
          if(curr.data.equals(data)){  
            //判断是什么节点  
            if(curr == head){   //如果删除的是头节点  
                //System.out.println("delete head node");  
                head = curr.next;  
                b = true;  
                return;  
            }  
            if(curr.next == head){ //如果删除的是尾节点  
                //System.out.println("delete tail node");    
                prev.next = head;  
                b = true;  
                return;  
            }  
            else{  //  如果删除的是中间节点(即非头节点或非尾节点)  
                //System.out.println('n'+"delete center node");  
                prev.next = curr.next;  
                b = true;  
                return;  
            }  
         }  
         prev = curr;  
         curr = curr.next;   
        }

        if(b == false){  
           System.out.println("没有这个数据" + data);  
        }     

    }  

    void solve(int n,int m){
        Node preNext = head;
        //T[] ans = new T[n + 1];
        int ansnum = 0;
        while (preNext.next != preNext){
            int cnt = 1;
            while (cnt < m){
                preNext = preNext.next;
                cnt ++;
            }
            System.out.print(preNext.data + " ");
            //ans[ansnum ++] = preNext.data;
            delete(preNext.data);
            preNext = preNext.next;
        }
        //for (int i = 0; i < ansnum; i ++){
        //    System.out.print(ans[i] + " ");
        //}
        System.out.println(preNext.data);
    }
}

public class ex1{
    public static void main(String[] args){
        LinkList mylist = new LinkList();
        Scanner in = new Scanner(System.in);
        while (in.hasNext()){
            Integer n = in.nextInt();
            Integer m = in.nextInt();
            mylist.addHead(1);
            for (int i = 2; i <= n; i ++){
                mylist.insert(i);
            }
            System.out.println("原顺序");
            mylist.show();
            System.out.println("出列顺序");
            mylist.solve(n,m);
        }

    }
}
/* 显示结果
 * 30 6
 * 原顺序
 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
 * 21 22 23 24 25 26 27 28 29 30 
 * 出列顺序
 * 6 12 18 24 30 7 14 21 28 5 15 23 2 11 22 3 16 27 10 
 * 26 13 1 20 17 9 19 29 25 8 4
 * 10 6
 * 原顺序
 * 1 2 3 4 5 6 7 8 9 10 
 * 出列顺序
 * 6 2 9 7 5 8 1 10 4 3
 * 8 2
 * 原顺序
 * 1 2 3 4 5 6 7 8 
 * 出列顺序
 * 2 4 6 8 3 7 5 1
 * 40 9
 * 原顺序
 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
 * 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 
 * 出列顺序
 * 9 18 27 36 5 15 25 35 6 17 29 40 12 24 38 11 26 1 
 * 16 32 8 28 4 23 7 31 14 39 30 20 13 10 19 22 37 33 34 21 2 3
 * */

网上找到一个写的不错的证明:
要证明一个东西:若forall x,y in mathbb{N}, N mid A_0 x+B_0 y,则A equiv A_0 i ~(mod N), ~B equiv B_0 i ~(mod N), ~(0 le i < N)N mid Ax+By的充要条件。

证明:

1)充分性:显然。

2)必要性:

N mid A_0 x+B_0 y,则 N mid Ax+By

=> 若A_0 x+B_0 y equiv 0 ~(mod N),则(A-A_0 i)x+(B-B_0 i)y equiv 0 ~(mod N)

=> left{begin{array}{l}A equiv A_0 cdot (i+1) ~(mod N)\ B equiv B_0 cdot (i+1) ~(mod N)end{array}right.

left{begin{array}{l}A equiv A_0 cdot i ~(mod N)\ B equiv B_0 cdot i ~(mod N)end{array}right.

上面的网址:http://d.ream.at/sgu-119/

自己想的时候并没有那么复杂

ax + by = kn,那么acx + by = kcn的,如果c > n 的话,就可以提取出一个anx + bny = knn出来约去,所以所有的可能就是枚举c 为 0到n - 1,每次(ac % n, bc % c)就是一组。

其实这样子还是有重复的,这个式子首先得除掉gcd(a,b,n)然后得出来的r作为c枚举的范围,不然范围比较大?反正减小范围,因为枚举0到n-1会有重复的ab组。

还有那个上面的移位再比较实在有点赞~少写点代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* From: Lich_Amnesia
* Time: 2014-03-11 22:39:02
*
* SGU 119
* */
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
using namespace std;

const int INF = ~0u>>1;
typedef pair <int,int> P;
#define MID(x,y) ((x+y)>>1)
#define iabs(x) ((x)>0?(x):-(x))
#define REP(i,a,b) for(int i=(a);i<(b);i++)
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
#define mp make_pair
#define print() cout<<"--------"<<endl
int ans[10100];
int gcd(int a,int b){
return b == 0 ? a : gcd(b, a % b);
}

int main(){
int n;
int a,b;
scanf("%d%d%d", &n, &a, &b);
int r = n / gcd(gcd(a,b),n);
for (int i = 0; i < r; i ++){
ans[i] = (a * i % n << 16) + b * i % n;
}
sort(ans,ans + r);
printf("%dn", r);
for (int i = 0; i < r; i ++){
printf("%d %dn",ans[i] >> 16, ans[i] & 0xffff);
}
return 0;
}

  最近在帮某陆老师搞一个小车的程序,虽然只是一小个模块,不过已经弄得吃不消了。

  接触了一下Qt下的编程,然后好不容易才把OpenGL给调试了不会出错。

  把遇到的问题汇总一下。

  首先,安装Qt+openGL,官网上下+google基本不会有多大问题。(评判装成功就是你Qt能不能跑Qt中的样例程序,那个3d的hello Qt程序)

  可以看这个:http://blog.csdn.net/silangquan/article/details/7845501

  然后就开始蛋疼了。

  找到了那个经典的Nehe的教程,然后就开始头文件找不到,什么reference出错,然后看Qt的样例又貌似没用到glut.h之类的头文件。

  网上的代码的看到的都是#include <GL/GLUT.h>之类的形式,怎么都找不到,火起来就直接在ubuntu下搜glut.h这个文件,然后发现竟然是小写的,改成小写就行了。大概如下:

1
2
#include <GL/glut.h>
#include <GL/glu.h>

 之后又报错。原来是.pro文件得加opengl才行,于是就把所有的都添加了

1
QT  += core gui opengl widgets

  还是不行,有好些函数全都是reference出错,又没有引用错误,到stackoverflow上查到了,还得在.pro文件下加lib,如下

1
LIBS+=-lglut -lGLU

  上面两个头文件所需要的。

  这样子基本就行了。

  还有一点要搞清的,opengl可绘图,Qt下也有绘图的库,搞混了就不好了,函数什么的都不一样。