【11/10】模拟赛
前言
第一次没写出全AC代码。
第一题 distinct
【题目描述】
陶陶为了给一道平面几何题出数据,需要产生 N 个点(x[i],y[i])。已知x,y是由伪随机函数顺序产生,即:
X[i+1] = (X[i]*Ax+Bx+i) mod Cx (X[1], Ax,Bx,Cx 是事先给定的)
Y[i+1] = (Y[i]*Ay+By+i) mod Cy (Y[1], Ay,By,Cy 是事先给定的)
这样,就可以快速连续产生很多点坐标(X[i], Y[i])。
不幸的是,这样产生的点有可能有相同的,虽然这种几率很少,但严谨的陶陶不允许这种事发生。陶陶要求你帮助他解决最少要产生前多少项时,正好有 N 个不相同的点。
【输入格式】
第一行。一个整数 N .
第二行:4个整数 X[1]、 Ax、Bx、Cx .
第三行:4个整数 Y[1]、 Ay、By、Cy .
【输出格式】
一个整数 M 。表示最少要连续产生 M 个点,正好有 N 个不相同的点。数据保证有答案。
【样例输入】
21
2 4 3 6
5 2 3 13
【样例输出】
24
【数据范围】
1<=N<=1,000,000, 其它所有数据都在[1...1,000,000,000]范围内。
【分析】
AC代码我不会。
有两个同学用HASH写的,但是我改写成CPP后还是超时。简直就是拼人品的题目。
代码是30分的二叉搜索树。
第二题 Allbarns
【题目描述】
农民约翰打算建一个新的矩形谷仓。但是,矩形谷仓的4个角落不能在落在软土路基上,只能落在一些固定点上。现在,他已经找到地面上有N(4 <= N <= 1,000)个点,角落只可以落在这些点上。他想知道依次每加多一个点,可以建立新谷仓的方法数量,请你帮助他找到答案。
【输入格式】
第1行:一个整数,N
第2行至N +1行:每行有两个被空格分隔的整数的x,y,作为一个点的坐标。
所有的x,y都不会超过16,000。所有点都是不同的。
【输出格式】
共 N 行:每行表示当前可以建立的新的谷仓的数目。
【样例输入】
8
1 2
1 -2
2 1
2 -1
-1 2
-1 -2
-2 1
-2 –1
【样例输出】
0
0
0
0
0
1
3
6
【分析】
AC代码我也不会。
我的代码是N^4的。但是过了7个点。枚举两个点,向量乘法判断直角,然后枚举第四个点。
第三题 cubes
【题目描述】
FJ和Best用 N (1 <= N <= 30,000)块相同的小立方块玩游戏,小方块编号为1..N。开始时,小方块都单独分开的,每个看成一个柱子,即有 N 柱子。FJ要Best做 P(1 <= P <= 100,000) 个操作,操作有两种类型:
(1) FJ要求Best把X号方块所在的柱子放到Y号所在的柱子上面,成一个新柱子。
(2)FJ要求Best计算X号方块所在柱子,它下面有多少个小方块。
请编个程序,帮助Bet计算。
【输入格式】
第一行:一个整数 P
第2..P+1行:第i+1行表示第i个FJ要求的合法操作。如果这行以'M'开头,后面有两个整数 X,y 表示要进入(1)操作。 如果这行以'C'开头,后面有一个整数 X,表示要求计算X所在柱子下面的方块个数。
注:所有操作都是合法的。N 并没有出现在输入文件中。
【输出格式】
依次要求计算的值,每次一行。
【样例输入】
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
【样例输出】
1
0
2
【分析】
并查集。
before[x]是x上面有多少个数。count[x]代表集合个数。
第四题 friend
【题目描述】
有一个镇有N个居民。当然其中有许多人是朋友的关系。根据有名的谚语:“我朋友的朋友也是我的朋友”,所以如果A和B是朋友,B和C是朋友,那么A和C也是朋友。
你的任务是算出在这个镇中最大的朋友集团为多少人。
【输入格式】
输入文件的第一行有2个正整数 N 和 M 。N代表镇上居民的数目(1 <= N <= 30000 ),M 代表这些居民中朋友关系的数目( 0 <= M <= 30000)。接下来的M行每行有2个整数A,B( 1 <= A,B <= N , A不等于B),代表A,B为朋友关系。这M行中可能有的会重复出现。
【输出格式】
输出文件仅一行,在这个镇中最大的朋友集团为多少人。
【样例输入】
10 12
1 2
3 1
3 4
5 4
3 5
4 6
5 2
2 1
7 10
1 2
9 10
8 9
【样例输出】
6
【分析】
比第三题简单的并查集。
代码
第一题
#include <stdio.h> #include <stdlib.h> #include <time.h> #define MAXN 1000010 #define mmm 10000000 long long n,m,lx,ly,xx,yy,ax,bx,cx,ay,by,cy; int tot,root; struct tn { int left,right; long long x,y; } t[MAXN]; bool ins(int *x) { if (*x == 0) { *x = ++tot; t[*x].left = t[*x].right = 0; t[*x].x = xx; t[*x].y = yy; return 1; } else { if (t[*x].x == xx && t[*x].y == yy) return 0; if (xx < t[*x].x) return ins(&t[*x].left); if (xx == t[*x].x) { if (yy < t[*x].y) return ins(&t[*x].left); return ins(&t[*x].right); } if (xx > t[*x].x) return ins(&t[*x].right); } } int main() { freopen("distinct.in","r",stdin); freopen("distinct.out","w",stdout); scanf("%lld",&n); scanf("%lld%lld%lld%lld%lld%ld%lld%lld",&lx,&ax,&bx,&cx,&ly,&ay,&by,&cy); --n; xx = lx; yy = ly; ins(&root); while (n) { ++m; xx = (lx * ax + bx + m) % cx; yy = (ly * ay + by + m) % cy; if (ins(&root)) --n; lx = xx; ly = yy; } printf("%lld\n",m + 1); return 0; }
第二题
#include <stdio.h> #define MAXN 1000 struct ss { int x,y; } a[MAXN]; int n,ans,x1,y1,x2,y2,tx,ty; bool check(int x1,int y1,int x2,int y2) { return x1 * x2 + y1 * y2 == 0; } int main() { freopen("allbarns.in","r",stdin); freopen("allbarns.out","w",stdout); scanf("%d",&n); for (int i = 1;i <= n;++i) { scanf("%d%d",&a[i].x,&a[i].y); for (int j = 1;j < i;++j) { x1 = a[j].x - a[i].x; y1 = a[j].y - a[i].y; for (int k = j + 1;k < i;++k) { x2 = a[k].x - a[i].x; y2 = a[k].y - a[i].y; if (check(x1,y1,x2,y2)) { tx = a[i].x + x1 + x2; ty = a[i].y + y1 + y2; for (int t = 1;t < i;++t) if ((a[t].x == tx) && (a[t].y == ty)) { ++ans; break; } } } } printf("%d\n",ans); } return 0; }
第三题
#include <stdio.h> #include <stdlib.h> #define maxn 30010 int root[maxn],before[maxn],count[maxn]; int n,x,y; char c; int froot(int x) { if (!root[x]) return x; int te = froot(root[x]); before[x] = before[root[x]] + before[x]; root[x] = te; return te; } void merge(int x,int y) { int rx = froot(x),ry = froot(y); if (rx == ry) return; root[rx] = ry; before[rx] += count[ry]; count[ry] += count[rx]; } int main() { freopen("cubes.in","r",stdin); freopen("cubes.out","w",stdout); for (int i = 1;i <= 30000;++i) count[i]=1; scanf("%d",&n); scanf("%c",&c); for (int i = 1;i <= n;++i) { scanf("%c",&c); if (c=='M') { scanf("%d%d",&x,&y); merge(y,x); } else { scanf("%d",&x); int te = froot(x); printf("%d\n",count[te] - before[x] - 1); } scanf("%c",&c); } return 0; }
第四题
#include <stdio.h> #define MAXN 30010 int fr[MAXN],cou[MAXN]; int n,m,x,y,ans; int froot(int x) { if (!fr[x]) return x; int te = froot(fr[x]); fr[x] = te; return te; } void mer(int x,int y) { int rx = froot(x),ry = froot(y); fr[ry] = rx; cou[rx] += cou[ry]; } int main() { freopen("friend.in","r",stdin); freopen("friend.out","w",stdout); scanf("%d%d",&n,&m); for (int i = 1;i <= n;++i) cou[i] = 1; for (int i = 1;i <= m;++i) { scanf("%d%d",&x,&y); int rx = froot(x),ry = froot(y); if (rx != ry) mer(x,y); } for (int i = 1;i <= n;++i) if ((!fr[i]) && (cou[i] > ans)) ans = cou[i]; printf("%d\n",ans); return 0; }