1. 程式人生 > 實用技巧 >2020.11.19 刷題記錄

2020.11.19 刷題記錄

1 tran

題意:給出一個圖,求從任一位置射入光束後光束存在的最長時間與射入方向。若存在多種時間相同的,輸出字典序最小的方案。
題解:比較water的大模擬,題意看對很快能想出來

CODE
 
#include
using namespace std;
#define re register
#define LL long long
#define DB double
#define il inline
#define For(x,a,b) for(re int x=a;x<=b;x++)
#define For2(x,a,b) for(re int x=a;x>=b;x--)
#define LFor(x,a,b) for(re LL x=a;x<=b;x++)
#define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
#define Abs(x) ((x>0)? x:-x)
#define INF 100000000
#define pii pair
#define fi first
#define se second
#define mabs(x) ((abs(x))==(0)? (INF):(abs(x)))
int gi()
{
    int res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    if(ch=='-') fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
}
LL gl()
{
    LL res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    if(ch=='-') fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
}
char mp[4]={'U','D','L','R'};
int n,m,a[505][505];
bool mrk[505][505][4][4];
int Time,ans[10];
int solve(pii POS,pii D)
{
	int x=POS.fi,y=POS.se,dx=D.fi,dy=D.se;
	if(x<1 || x>n || y<1 || y>m || a[x][y]==2)
		return Time;
	if(mrk[x][y][dx+1][dy+1])
			return INF;
	mrk[x][y][dx+1][dy+1]=true;
	Time++;
	if(a[x][y]==0) return solve(pii(x+dx,y+dy),D);
	int ndx=dy*a[x][y],ndy=dx*a[x][y];
	return solve(pii(x+ndx,y+ndy),pii(ndx,ndy));
}
void init()
{
	Time=0;
	memset(mrk,0,sizeof(mrk));
}

int main()
{
// freopen("tran.in","r",stdin);
// freopen("tran.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n>>m;
For(i,1,n)
For(j,1,m)
{
char t;
cin>>t;
if(t'/')a[i][j]=-1;
else if(t
'\') a[i][j]=1;
else if(t'.') a[i][j]=0;
else a[i][j]=2;
}
pii ray;
cin>>ray.fi>>ray.se;
init();
ans[0]=solve(ray,pii(-1,0));
init();
ans[1]=solve(ray,pii(1,0));
init();
ans[2]=solve(ray,pii(0,-1));
init();
ans[3]=solve(ray,pii(0,1));
int ind=-1;
For(i,0,3) if(ind

-1 || ans[ind]<ans[i])ind=i;
cout<<mp[ind]<<endl;
if(ans[ind]>=INF) cout<<"Voyager"<<endl;
else cout<<ans[ind]<<endl;
return 0;
}

2 week

題意:有兩個數x,y,進行n次操作,對於第i次,有如下兩種操作型別可任選一:

1. x+=a[i],y-=b[i]
2. x-=c[i],y+=d[i]

求最終可以得到的\(x*y\)的最大值
題解:送分題。。。直接列舉\(2^n\)種方案,記錄個最大值就行。然後記得開long long。

CODE
 
#include
using namespace std;
#define re register
#define LL long long
#define DB double
#define il inline
#define For(x,a,b) for(re int x=a;x<=b;x++)
#define For2(x,a,b) for(re int x=a;x>=b;x--)
#define LFor(x,a,b) for(re LL x=a;x<=b;x++)
#define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
#define Abs(x) ((x>0)? x:-x)
#define INF 1000000000009
#define mabs(x) ((abs(x))==(0)? (INF):(abs(x)))
int gi()
{
    int res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    if(ch=='-') fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
}
LL gl()
{
    LL res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    if(ch=='-') fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
}
int n,a[20],b[20],c[20],d[20];
LL ans,X,Y;
void dfs(int pos) 
{
    if (pos>n) 
	{
        ans=max(ans,X*Y);
        return ;
    }
    LL t1=X,t2=Y;
    X+=a[pos],Y=max((LL)0,Y-b[pos]);
    dfs(pos+1);
    X=t1,Y=t2;
    Y+=c[pos],X=max((LL)0,X-d[pos]);
    dfs(pos+1);
    X=t1,Y=t2;
}
int main()
{
    freopen("week.in","r",stdin);
    freopen("week.out","w",stdout);
    ans=X=Y=0;
    n=gi();
    For(i,1,n) a[i]=gi(),b[i]=gi(),c[i]=gi(),d[i]=gi();
    dfs(1);
    printf("%lld\n",ans);
    return 0;
}
  

3 duty

題意:有一個\(n*m\)的黑白方格圖,每次詢問其中子矩形內部的黑色連通塊個數,保證任意兩個聯通的黑格間僅有一條路徑
題解:由上面加粗的部分,我們可以知道此圖能構造出一張DAG,那麼聯通塊=點數-邊數
二位字首和維護一下點數和邊數即可。注意每次詢問考慮的是矩形內部的連通塊。

CODE

#include
using namespace std;
#define re register
#define LL long long
#define DB double
#define il inline
#define For(x,a,b) for(re int x=a;x<=b;x++)
#define For2(x,a,b) for(re int x=a;x>=b;x--)
#define LFor(x,a,b) for(re LL x=a;x<=b;x++)
#define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
#define Abs(x) ((x>0)? x:-x)
#define INF 1000000000009
#define mabs(x) ((abs(x))==(0)? (INF):(abs(x)))
int gi()
{
    int res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    if(ch=='-') fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
}
LL gl()
{
    LL res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    if(ch=='-') fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
}
int n,m,q;
int pre_P[2005][2005],pre_E[2005][2005];
int pa[2005][2005],pb[2005][2005];
char s[2005][2005];

int main()
{
n=gi(),m=gi(),q=gi();
For(i,1,n)
scanf("%s",s[i]+1);
For(i,1,n)
For(j,1,m)
{
pre_P[i][j]=pre_P[i-1][j]+pre_P[i][j-1]-pre_P[i-1][j-1]+(s[i][j]'1'? 1:0);
pre_E[i][j]=pre_E[i-1][j]+pre_E[i][j-1]-pre_E[i-1][j-1]+(s[i][j]
'1'? (s[i][j]s[i][j-1]? 1:0)+(s[i][j]s[i-1][j]? 1:0):0);
pa[i][j]=pa[i-1][j]+(s[i][j]'1'&&s[i][j]s[i-1][j]? 1:0);
pb[i][j]=pb[i][j-1]+(s[i][j]'1'&&s[i][j]s[i][j-1]? 1:0);
}
// printf("%d\n",pre_E[3][3]);
re int np,ne,x,y,xx,yy;
For(i,1,q)
{
x=gi(),y=gi(),xx=gi(),yy=gi();
np=pre_P[xx][yy]-pre_P[xx][y-1]-pre_P[x-1][yy]+pre_P[x-1][y-1];
ne=pre_E[xx][yy]-pre_E[xx][y]-pre_E[x][yy]+pre_E[x][y]+pa[xx][y]-pa[x][y]+pb[x][yy]-pb[x][y];
printf("%d\n",np-ne);
}
return 0;
}
/*
5 5 6
11010
01110
10101
11101
01010
1 1 5 5
1 2 4 5
2 3 3 4
3 3 3 3
3 1 3 5
1 1 3 4

3 4 4
1101
0110
1101
1 1 3 4
1 1 3 1
2 2 3 4
1 2 2 4
*/

4 fly

題意:(偷懶)

題解:進行仔細的長時間的分析研究(霧),發現我們要求的是逆序對數,但瞄一眼空間限制,32MB,在MLE的面前我選擇妥協。
繼續思考,發現a很小,於是從a入手,發現\(x_i\)構成一個等差數列,於是只要算小於a的逆序對數,剩餘的可直接遞推計算出來。

CODE

#include
using namespace std;
#define re register
#define LL long long
#define DB double
#define il inline
#define For(x,a,b) for(re int x=a;x<=b;x++)
#define For2(x,a,b) for(re int x=a;x>=b;x--)
#define LFor(x,a,b) for(re LL x=a;x<=b;x++)
#define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
#define Abs(x) ((x>0)? x:-x)
#define INF 1000000000009
#define mabs(x) ((abs(x))==(0)? (INF):(abs(x)))
int gi()
{
	int res=0,fh=1;char ch=getchar();
	while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
	if(ch=='-') fh=-1,ch=getchar();
	while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
	return fh*res;
}
LL gl()
{
	LL res=0,fh=1;char ch=getchar();
	while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
	if(ch=='-') fh=-1,ch=getchar();
	while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
	return fh*res;
}
int n,x,a,mod;
int tr[500005];
int flag,pls,cut;
LL ans;
int lowbit(int x){return x&-x;}
void change(int x)
{
	for(int i=x;i<=a;i+=lowbit(i))
		tr[i]++;
}
int ask(int x)
{
	int res=0;
	for(int i=x;i;i-=lowbit(i))
		res+=tr[i];
	return res+1;
}
int main()
{
	freopen("fly.in","r",stdin);
	freopen("fly.out","w",stdout);
	n=gi(),x=gi(),a=gi(),mod=gi();
	if(x