Hack ItTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1020 Accepted Submission(s): 354 Special Judge Problem Description Tonyfang is a clever student. The teacher is teaching he and other students "bao'sou".The teacher drew an n*n matrix with zero or one filled in every grid, he wanted to judge if there is a rectangle with 1 filled in each of 4 corners. He wrote the following pseudocode and claim it runs in O(n2): let count be a 2d array filled with 0s iterate through all 1s in the matrix: suppose this 1 lies in grid(x,y) iterate every row r: if grid(r,y)=1: ++count[min(r,x)][max(r,x)] if count[min(r,x)][max(r,x)]>1: claim there is a rectangle satisfying the condition claim there isn't any rectangle satisfying the conditionAs a clever student, Tonyfang found the complexity is obviously wrong. But he is too lazy to generate datas, so now it's your turn. Please hack the above code with an n*n matrix filled with zero or one without any rectangle with 1 filled in all 4 corners. Your constructed matrix should satisfy 1≤n≤2000 and number of 1s not less than 85000. Input Nothing. Output The first line should be one positive integer n where 1≤n≤2000. Sample Input (nothing here) Sample Output 3 010 000 000 (obviously it's not a correct output, it's just used for showing output format) Source |
这个题真的想了好久,基本4个多小时,到最后也没推出来,真的难受,赛后听了大佬题解,原来是数论构造,然后同学再讲解了下终于明白了。
题意:
就是构造一个少于2000*2000的数字矩阵,然后在其中填写至少85000个点,但要保证这些点不构成矩形(就是边角不能有四个点)。
题解:
你先找一个最小质数,要平方大于你要构造矩阵边长,比如2000,就选择n = 47,因为这样才不会重复。
例如当n=5时,分为五大板块,构造一个n*n的矩阵如下:
i | 0 1 2 3 4
0 | 10000 10000 10000 10000 10000
1 | 10000 01000 00100 00010 00001
2 | 10000 00100 00001 01000 00010
3 | 10000 00010 01000 00001 00100
4 | 10000 00001 00010 00100 01000
5 | 01000 01000 01000 01000 01000
6 | 01000 00100 00010 00001 10000
.....
规律就是每一行每一个方块的1位置每次都会加上i然后去模n
n行一轮回后将第一次的内容全部往右挪一位就好
#include<bits/stdc++.h>
using namespace std;
struct node {
int l, r;
} edge[100005];
int ans[100005];
int cmp(node a, node b) {
if(a.l == b.l) {
return a.r < b.r;
}
return a.l < b.l;
}
int main() {
int t, a, b, x, y, numax, numin;
scanf("%d", &t);
while (t--) {
memset(ans, 0, sizeof(ans));
priority_queue<int, vector<int>, greater<int> >dong;
queue<int>pu;
numax = 999999;
scanf("%d %d", &a, &b);
for (int i = 1; i <= a; i++) {
dong.push(i);
ans[i] = -1;
//printf("!!%d\n",q.top());
}
//printf("%d\n",q.top());
for (int i = 1; i <= b; i++) {
scanf("%d %d", &edge[i].l, &edge[i].r);
}
sort(edge+1, edge+b+1, cmp);
int ml = 1, mr = 1;
for(int i = 1; i <= b; i++) {
if(edge[i].l != edge[i+1].l || i == b) {
for(int j = ml; j < edge[i].l; j++) {
if(ans[j] == -1) {
ans[j] = 1;
} else {
dong.push(ans[j]);
}
}
for(int j = mr; j <= edge[i].r; j++) {
if(ans[j] == -1) {
ans[j] = dong.top();
dong.pop();
}
}
ml = edge[i].l;
mr = max(mr, edge[i].r);
}
}
if(ans[1] == -1) {
ans[1] = 1;
}
printf("%d", ans[1]);
for(int i = 2; i <= a; i++) {
if(ans[i] == -1) {
ans[i] = 1;
}
printf(" %d", ans[i]);
}
puts("");
}
}