考试考得没有什么感觉,可能是太难了吧
第一题,用线段树分治优化掉了一个n,但是求答案的没能优化掉
第二题,直接短路了,没考虑全,打了个bfs就走了,于是只有30分
第三题,看出来了必须是一行或者一列这个结论,然鹅觉得那些分类讨论忒难了,于是打了个全联通的就溜号了,不告诉你我全联通的都没打对,其实不是没打对,是忘记把2判掉了......
T1 数学题
所以说那句“题面上有算法,别看,肯定不是正解!!”确实是有道理哈!
于是我在知道这句话的前提下......想找规律想了一个小时
后来想要开始打暴力了,一开始的暴力是\(\mathcal{n^5}\)的
然后想了想可以变成\(\mathcal{n^4}\),然后又想了想变成了\(\mathcal{n^3logn}\)
就止步于此了,后来发现可以\(\mathcal{O(1)}\)的到是否可以合成新数
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*t;
}
const int N=1005;
int n,m,bas;char ch[N];
bitset<N> lba[N],sta[N],bit[N],tmp,con;
int cba,vba[N],ans[N][N];
int ins(){
fo(i,1,m){
if(!tmp[i])continue;
if(vba[i])tmp^=lba[i];
else {
lba[i]=tmp;vba[i]=1;cba++;sta[i][i]=1;
fo(j,i+1,m)if(vba[j]&&lba[i][j])lba[i]^=lba[j],sta[i]^=sta[j];
fo(j,1,i-1)if(vba[j]&&lba[j][i])lba[j]^=lba[i],sta[j]^=sta[i];
return i;
}
}return 0;
}
void del(int x){
fo(i,1,m)if(i!=x&&vba[i]&&sta[i][x])lba[i]^=lba[x],sta[i]^=sta[x];
fo(i,1,m)if(i!=x&&vba[i]&&sta[x][i])lba[x]^=lba[i],sta[x]^=sta[i];
lba[x].reset();cba--;vba[x]=0;sta[x][x]=0;
}
struct XDS{
#define ls x<<1
#define rs x<<1|1
vector<int> vec[N*4],ji[N*4];
void insert(int x,int l,int r,int ql,int qr,int id){
if(ql>qr)return ;
if(ql<=l&&r<=qr)return vec[x].push_back(id),void();
int mid=l+r>>1;
if(ql<=mid)insert(ls,l,mid,ql,qr,id);
if(qr>mid)insert(rs,mid+1,r,ql,qr,id);
}
void dfs(int x,int l,int r){
for(int i:vec[x])tmp=bit[i],ji[x].push_back(ins());
if(l==r){
tmp=bit[l];int ret=ins();con.reset();
if(!ret){fo(i,1,m)ans[l][i]=!(lba[i].count()==1);}
else {
fo(i,1,m)con[i]=(lba[i].count()==1);del(ret);
fo(i,1,m)ans[l][i]=-(!(lba[i].count()==1)&&con[i]);
}
for(int i:ji[x])if(i){del(i);}
return ;
}
int mid=l+r>>1;dfs(ls,l,mid);dfs(rs,mid+1,r);
for(int i:ji[x])if(i){del(i);}
}
#undef ls
#undef rs
}xds;
signed main(){
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
n=read();m=read();//tmp.reset();cout<<tmp[0]<<endl;
fo(i,1,n){
scanf("%s",ch+1);
fo(j,1,m)bit[i][j]=ch[j]-'0';
}
fo(i,1,n)tmp=bit[i],ins();bas=cba;
fo(i,1,m)if(vba[i])del(i);
fo(i,1,n){
xds.insert(1,1,n,1,i-1,i);
xds.insert(1,1,n,i+1,n,i);
}
xds.dfs(1,1,n);
fo(i,1,n){
fo(j,1,m){
if(ans[i][j]==0)printf("0");
else if(ans[i][j]<0)printf("-");
else if(ans[i][j]>0)printf("+");
}
printf("\n");
}
return 0;
}
T2 构造题
一个非常暴力的思路就是捡着最小的可以填的颜色填,直接广搜就行了,但是很难保证正确性
于是我们想到一个更暴力的但是有点慢的做法,既然选最小的不能保证正确性,那我们就一位一位的搜填什么颜色,然而你以为这样会爆蛋,事实证明他切掉了,但是我一条链就给他卡没了,完全链
然后我们发现这个4就非常的离奇,考虑出题人为啥要给坐标,并且规定了斜率??
其实就是告诉你一个点最多连八条边,不可能出现四个点以上的子完全图
于是我们按照坐标排序,这样对边定向,一个点最多4条入遍,那么我们一旦碰到没法选的,直接搜回去...
上面纯属口胡,不要看了,我写的是第二种
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*t;
}
const int N=1e4+5;
int n,m,k,ans[N];
struct E{int to,nxt;}e[N*2*2];
int head[N],rp;
void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
int lim[N][6];
void dfs(int x){
if(x==n+1){
fo(i,1,n)printf("%d\n",ans[i]);
exit(0);
}
for(int i=head[x];i;i=e[i].nxt)lim[x][ans[e[i].to]]=1;
fo(i,1,k)if(!lim[x][i])ans[x]=i,dfs(x+1);ans[x]=0;
fo(i,1,k)lim[x][i]=0;
}
signed main(){
freopen("construct.in","r",stdin);
freopen("construct.out","w",stdout);
n=read();m=read();k=read();
fo(i,1,n){
int x=read(),y=read();
}
fo(i,1,m){
int x=read(),y=read();
add_edg(x,y);add_edg(y,x);
}
dfs(1);
return 0;
}
T3 网格图构造题
不会,只会一个全联通的,而且写的贼麻烦......
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*t;
}
const int N=4e5+5;
int n,m,k;
vector<int> ans[N];
struct LIM{int xa,ya,xb,yb,b;}lim[N];
void all(int xs,int ys,int xt,int yt){
int nn=xt-xs+1,mm=yt-ys+1;
int xx=xs-1,yy=ys-1;
if(nn&1){
if((nn>>1)&1){
for(int j=1;j*2<=mm;j++){
if(j&1){
for(int i=1;i*2<=nn;i++){
if(i&1){
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
else {
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
}
ans[xt][j*2-1+yy]=4;ans[xt][j*2+yy]=3;
}
else {xx++;
for(int i=nn>>1;i;i--){
if(((nn>>1)-i+1)&1){
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
else {
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
}xx--;
ans[xs][j*2-1+yy]=4;ans[xs][j*2+yy]=3;
}
}
}
else {
for(int j=1;j*2<=mm;j++){
if(j&1){
for(int i=1;i*2<=nn;i++){
if(i&1){
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
else {
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
}
ans[xt][j*2-1+yy]=4;ans[xt][j*2+yy]=3;
}
else {xx++;
for(int i=nn>>1;i;i--){
if(((nn>>1)-i+1)&1){
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
else {
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
}xx--;
ans[xs][j*2-1+yy]=4;ans[xs][j*2+yy]=3;
}
}
}
}
else if(mm&1){
if((mm>>1)&1){
for(int i=1;i*2<=nn;i++){
if(i&1){
for(int j=1;j*2<=mm;j++){
if(j&1){
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
else {
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
}
ans[i*2-1+xx][yt]=2;ans[i*2+xx][yt]=1;
}
else {yy++;
for(int j=mm>>1;j;j--){
if(((mm>>1)-j+1)&1){
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
else {
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
}yy--;
ans[i*2-1+xx][ys]=2;ans[i*2+xx][ys]=1;
}
}
}
else {
for(int i=1;i*2<=nn;i++){
if(i&1){
for(int j=1;j*2<=mm;j++){
if(j&1){
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
else {
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
}
ans[i*2-1+xx][yt]=2;ans[i*2+xx][yt]=1;
}
else {yy++;
for(int j=mm>>1;j;j--){
if(((mm>>1)-j+1)&1){
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
else {
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
}yy--;
ans[i*2-1+xx][ys]=2;ans[i*2+xx][ys]=1;
}
}
}
}
else {
fo(i,1,nn>>1)fo(j,1,m>>1){
if((i&1)==(j&1)){
ans[i*2-1+xx][j*2-1+yy]=4;
ans[i*2-1+xx][j*2+yy]=3;
ans[i*2+xx][j*2-1+yy]=4;
ans[i*2+xx][j*2+yy]=3;
}
else {
ans[i*2-1+xx][j*2-1+yy]=2;
ans[i*2-1+xx][j*2+yy]=2;
ans[i*2+xx][j*2-1+yy]=1;
ans[i*2+xx][j*2+yy]=1;
}
}
}
}
signed main(){
freopen("grid.in","r",stdin);
freopen("grid.out","w",stdout);
n=read();m=read();k=read();
fo(i,1,n)ans[i].reserve(m+5),ans[i].resize(m+3);
bool fl=true;
fo(i,1,k){
lim[i].xa=read();lim[i].ya=read();lim[i].xb=read();lim[i].yb=read();lim[i].b=read();
if(!lim[i].b)fl=false;
}
if(fl){
all(1,1,n,m);
if((n==2||m==2)&&k>1){printf("-1");return 0;}
fo(i,1,n){
fo(j,1,m){
if(ans[i][j]==1)printf("U");
if(ans[i][j]==2)printf("D");
if(ans[i][j]==3)printf("L");
if(ans[i][j]==4)printf("R");
}
printf("\n");
}return 0;
}
return 0;
}