Summary of 20181025-2

Keywords: Programming

Big Barn's huge cowshed
Chessboard making
Cow Line
pass notes around
OKR-Periods of Words

[All of the above are from WOJ]



Big Barn's huge cowshed

Matrix DP
dynamic programming
f [ i ] [ j ] = min ( min ( f [ i ] [ j-1] , f [ i - 1 ] [ j ] ) , f [ i - 1 ] [ j - 1 ] ) + 1 ;
f (i, j) denotes the edge length of the largest square with (i, j) at the lower right corner.
This location is updated only when no trees are planted.
Easy to understand

#include<bits/stdc++.h>
using namespace std;
int n,m,ans=0;
int a[1005][1005],f[1005][1005];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		a[x][y]=1;
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(!a[i][j]){//No trees 
				f[i][j]=min(min(f[i-1][j-1],f[i-1][j]),f[i][j-1])+1;
				if(f[i][j]>ans)ans=f[i][j];
			}
	printf("%d",ans);
	return 0;
}

Chessboard making

Matrix DP
dynamic programming
Hanging line method
qwq ^ __ ^ qwq Algorithms 2: Catenary + the largest square above
* _ * deepen the impression
Pretreatment and dyeing is very important!!!

#include<bits/stdc++.h>
using namespace std;
int n,m,ans1=0,ans2=0,tmp;
int a[2001][2001],f[2001][2001];//
void work1(){//Square 
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]){//See WOJ1787 
				f[i][j]=min(min(f[i-1][j-1],f[i-1][j]),f[i][j-1])+1;
				if(f[i][j]>ans1)ans1=f[i][j];
			}
}
int l[2001][2001],r[2001][2001];//Recent obstacles in the upper rectangle  
int dl[2001][2001],dr[2001][2001];//The nearest obstacle to the current line ()
int h[2001][2001];//height 
void work2(){
	for(int i=1;i<=n;i++){
		tmp=0;
		for(int j=1;j<=m;j++)//Calculate the nearest obstacle position on the left
			if(a[i][j])dl[i][j]=tmp;
			else{
				tmp=j;
				l[i][j]=0;//details 
			}
		tmp=m+1;
		for(int j=m;j>0;j--)//Calculate the nearest obstacle position on the left
			if(a[i][j])dr[i][j]=tmp;
			else{
				tmp=j;
				r[i][j]=m+1;//details 
			}
	}
	for(int i=1;i<=m;i++)r[0][i]=m+1;//details
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]){
				h[i][j]=h[i-1][j]+1;
				l[i][j]=max(l[i-1][j],dl[i][j]);//Calculating the Leftmost Obstacles of the Current Rectangle
                r[i][j]=min(r[i-1][j],dr[i][j]);//Calculate the right-most obstacle of the current rectangle
                ans2=max(ans2,h[i][j]*(r[i][j]-l[i][j]-1));
			}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			scanf("%d",&a[i][j]);
			if((i+j)%2)a[i][j]^=1;//Dye the opposite colour in the corresponding position
		}
	work1();
	work2();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			a[i][j]^=1;//Redyeing 
	memset(f,0,sizeof(f));
	memset(l,0,sizeof(l));
	memset(r,0,sizeof(r));
	memset(dl,0,sizeof(dl));
	memset(dr,0,sizeof(dr));
	memset(h,0,sizeof(h));
	work1();
	work2();
	printf("%d\n%d",ans1*ans1,ans2);//Maximum Square, Maximum Rectangle 
	return 0;
}

Cow Line

Cantor unfold
See for details xly

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,a[25],b[25];
ll fac[25];//Factorial 
ll contor(){
	ll res=0;
	for(int i=1;i<=n;i++){
		int t=0;
		for(int j=i+1;j<=n;j++)if(a[j]<a[i])t++;
		res+=t*1ll*fac[n-i];
	}
	return res;
}
bool vis[30];
void reverse_contor(ll x){
	memset(vis,0,sizeof(vis));
	x--;
	for(int i=1;i<=n;i++){
		ll t=x/fac[n-i];
		int j;
		for(j=1;j<=n;j++){
			if(!vis[j]){
				if(!t)break;
				t--;
			} 
		}
		b[i]=j;
		vis[j]=1;
		x%=fac[n-i];
	}
}
int main(){
	cin>>n>>m;
	fac[0]=1;
	for(int i=1;i<=n;i++)fac[i]=fac[i-1]*1ll*i;
	while(m--){
		char c;
		cin>>c;
		if(c=='P'){
			ll q;
			cin>>q;//Big K 
			reverse_contor(q);
			for(int i=1;i<=n;i++)printf("%d ",b[i]);
			printf("\n"); 
		}
		else{
			for(int i=1;i<=n;i++)
				cin>>a[i];
			printf("%lld\n",contor()+1);
		}
	}
	return 0;
}

pass notes around

Two way DP
dynamic programming
qwq

#include<bits/stdc++.h>
using namespace std;
int n,m,a[55][55];
int f[55][55][55];//One person's abscissa and another person's abscissa 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int e=1;e<=i+j-1&&e<=n;e++){
				if(i+j-e>m||(e==i&&(i!=n||j!=m)))continue;//!!!
				f[i][j][e]=max(max(f[i][j-1][e]/*Double left*/,f[i-1][j][e-1]/*Double upper*/),max(f[i][j-1][e-1]/*Left + upper*/,f[i-1][j][e]/*+ + left*/))+a[i][j]+a[e][i+j-e];
			}
	printf("%d",f[n][m][n]);
	return 0;
} 

OKR-Periods of Words

KMP
KMP's Mismatch Pointer Thought
?~ ?

#include<bits/stdc++.h>
#define ll long long
using namespace std;
char a[1000010];
int n,fail[1000010];
int main(){
    scanf("%d",&n);
    scanf("%s",a) ;
    int i,j;
    ll cnt=0;
    fail[0]=fail[1]=0;
    j=0;
    for(i=1;i<n;i++){//Solving next????
        while(j&&(a[i]!=a[j]))
    		 j=fail[j];
        j+=(a[i]==a[j]);
        fail[i+1]=j;
    }
    for(i=1;i<=n;i++){
        j=i;
        while(fail[j])
       		 j=fail[j];
        if(fail[i]!=0) fail[i]=j;//Memorization
        cnt+=i-j;
    }
    printf("%lld",cnt);
}

Posted by deveed on Wed, 23 Jan 2019 16:51:13 -0800