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