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