2019年8月6日本地題庫提高組 gcd+LIS+單調隊列優化+bfs+?

A 蛋糕切割

Garfield非常喜歡巧克力蛋糕。奇怪的是,她把蛋糕分成了N行M列的網格。饞嘴的她想知道,沿對角線的一刀能切到的網格數。
對於50%的數據,N,M ≤ 10^3,
對於100%的數據,N,M ≤ 10^9。

枚舉數據並分析可得,答案即n+m-gcd(m,n)

#include <cstdio>

using namespace std;

int n,m;

int gcd(int a,int b){
	 if (b==0) return a;
	 int k=gcd(b,a%b);
	 return k;
}

int main(){
	 scanf("%d%d",&n,&m);
	 if (n>=m) printf("%d",n+m-gcd(n,m));else
	     printf("%d",n+m-gcd(m,n));
}

B 膜拜神牛

Garfield聽說OI班有N頭神牛,每頭神牛有兩個屬性,算法能力和思維能力,分別以Ai和Bi表示。如果神牛i和神牛j滿足Ai ≥ Aj且Bi ≤ Bj,那麼兩位神牛會互相膜拜。Garfield認爲膜拜是不和諧的,所以她想知道,最大的不存在膜拜關係的子集大小。
對於40%的數據,N ≤ 10^3,
對於100%的數據,N ≤ 10^5。

以ai爲第一關鍵字,bi爲第二關鍵字排序,ai升序,bi降序
對排序後的bi求最長上升子序列
O(n log n)

#include <cstdio>
#include <algorithm>

using namespace std;int n,ans;

struct node{
	 int a,b;
}c[100005];
int f[100005];

bool comp(node a,node b){
 	if (a.a==b.a) return a.b>b.b;
	 return a.a<b.a;
}

int main(){
	 scanf("%d",&n);
	 for (int i=1;i<=n;i++)
		  scanf("%d%d",&c[i].a,&c[i].b);
	 sort(c+1,c+1+n,comp);
	 for (int i=1;i<=n;i++){
		  if (c[i].b>f[ans]){
			   f[++ans]=c[i].b;
		  }else{
			   int l=1,r=ans,k=0;
			   while (l<=r){
				    int mid=(l+r)/2;
			   	 if (f[mid]>=c[i].b) r=mid-1,k=mid;else l=mid+1;
			   }
			   f[k]=c[i].b;
		  }
	 }
	 printf("%d",ans);
}

C 矩形統計

Garfield小時候數學非常好,這與她喜歡數格子是分不開的。現在她有一張邊長爲N的方格紙(有若干破損),她想知道這張紙能夠裁出多少矩形。
對於50%的數據,N ≤ 20,
對於100%的數據,N ≤ 1000。
將破損表示爲1

010
010
000
把這樣的一張紙表示爲矩形

		0 0
		0 0
		000

這時就把矩形從左向右加入隊列,當後加的矩形比前面的矩形矮時,要彈出高的矩形高出的部分,並加入答案,然後把消掉高出部分的矩形加入後加的矩形,也就是後加的矩形寬度增加。
加入答案時,用矩形的高度*寬度(寬度:對於高度爲1的一行格子,可以取多少種矩形)
emm…開long long
矩形的高度用up[i][j]表示,即格子(i,j)向上多少個格子到破損格子

#include <cstdio>
#include <cstring>

using namespace std;int n,cw;

long long ans;
int up[5003][5003],a[5003][5003];
int w[5003],u[5003],h;
int s[5003];

int main(){
	 scanf("%d",&n);
	 for (int i=1;i<=n;i++)
	  for (int k=1;k<=i;k++)
		   s[i]+=i-k+1;
	 for (int i=1;i<=n;i++){
		  char ch[5003];
		  scanf("%s",ch+1);
	  for (int j=1;j<=n;j++) 
		   a[i][j]=ch[j]-'0';
	 }
	 for (int i=1;i<=n;i++){
		  for (int j=1;j<=n;j++) 
		  if (a[i][j])
		   for (int k=i+1;a[k][j]==0&&k<=n;k++)
		    up[k][j]=k-i;
	 }
	 for (int i=1;i<=n;i++)
		  for (int j=1;j<=n;j++)
		  if (a[i][j]==0&&up[i][j]==0) up[i][j]=i;
			 for (int i=1;i<=n;i++){
				h=0;
				for (int j=1;j<=n+1;j++)
				  if (up[i][j]==0){
				  	while (h){
						ans=(long long)ans+s[w[h]]*(u[h]-u[h-1]);
   						w[h-1]+=w[h];
						h--;
 				 	}
   					w[0]=0;
				  }else{
			          if (up[i][j]>u[h]) u[++h]=up[i][j],w[h]=1;else
			 	 {
 					   cw=0;
					    while (u[h]>up[i][j]&&u[h-1]>up[i][j]){
 				        	   cw+=w[h];
						   ans=(long long)ans+s[cw]*(u[h]-u[h-1]);
 						   h--;
					    }
  					  if (u[h]>up[i][j]) 
  					  cw+=w[h] , ans=(long long)ans+s[cw]*(u[h]-up[i][j]) , h--;
					    w[++h]=cw+1;u[h]=up[i][j];
				       while (u[h-1]==up[i][j]) w[h-1]+=w[h],h--;
 				  }
			  }
		 }
	 printf("%lld",ans);
}

D 逃亡路徑

由於不能與Garfield和睦相處,Odie決定逃亡。不幸的他逃到了一個矩形湖泊。湖泊的長爲N,寬爲M,初始時Odie位於位置(1,1)。Garfield想要知道可憐的Odie有到達位置(N,M)的最短路徑條數(不能跳出湖泊邊界)。另外,神奇的Odie移動方式類似國際象棋的騎士。
對於50%的數據,N ≤ 5,
對於100%的數據,N ≤ 100。
輸出一個整數,表示最短路徑的條數(模9901輸出即可)。

bfs暴搜啦

#include <cstdio>

using namespace std;

const int dx[10]={-2,-2,-1,1,2,2,1,-1};
const int dy[10]={-1,1,2,2,1,-1,-2,-2};
int n,m,ans;
int a[106][106],f[106][106];
int v[1000000][4],h,t;

void bfs(){
	 int flag=0;
	 t=1;v[1][0]=1;v[1][1]=1;v[1][2]=1;a[1][1]=1;f[1][1]=1;
	 while ((h<t)&&(!flag||v[h+1][2]==flag)){
		  int x=v[++h][0],y=v[h][1];
		  for (int i=0;i<8;i++)
		  if (x+dx[i]>0&&x+dx[i]<=n&&y+dy[i]>0&&y+dy[i]<=m){
		   	if (a[x+dx[i]][y+dy[i]]==0)   
		   		v[++t][0]=x+dx[i],v[t][1]=y+dy[i],v[t][2]=v[h][2]+1,a[x+dx[i]][y+dy[i]]=v[h][2]+1;
			if (a[x+dx[i]][y+dy[i]]==0||v[h][2]+1==a[x+dx[i]][y+dy[i]])   
			 	f[x+dx[i]][y+dy[i]]=(f[x+dx[i]][y+dy[i]]+f[x][y])%9901;
 			if (x+dx[i]==n&&y+dy[i]==m){
			    flag=v[h][2];
   			}
		  }
	 }
}

int main(){
	 scanf("%d%d",&n,&m);
	 bfs();
	 printf("%d",f[n][m]%9901);
}

E 矩形反色

gmh77有一個無限大的方格圖,由無限個1*1的格子構成,每個格子有黑白兩色。初始所有格子都是白色。

現在gmh77會進行n次操作,每次把一個矩形區域反色(即黑變白,白變黑),求n次操作後得出的圖形的周長(即邊界長)。

邊界的定義:定義一條長度爲1的線段在邊界上,當且僅當這條線段兩側的格子顏色不同。

注:輸入中給出的是格子的座標(不是點的座標)

希望我們都能像對方一樣勇敢。——蔣丞

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章