A-Jelly
題意:三維bfs,從(1,1,1)到(n,n,n)的最短距離
題解:bfs,寫的有點醜,還wa了一發。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int N=2e5+10;
const int Maxn=5e5+10;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
char s[110][110][110];
int disx[6],disy[6],disz[6];
int vis[110][110][110];
struct arr{
int x,y,z;
};
queue<arr>q;
int n;
void bfs(int x,int y,int z){
arr node;
node.x=x,node.y=y,node.z=z;
q.push(node);
vis[1][1][1]=0;
while(!q.empty()){
arr no=q.front();q.pop();
if(no.x==n && no.y==n && no.z==n){
vis[no.x][no.y][no.z]++;
return;
}
for(int i=0;i<6;i++){
int nx=no.x+disx[i];
int ny=no.y+disy[i];
int nz=no.z+disz[i];
if(nx<=0 || ny<=0 || nz<=0 || nx>n || ny>n || nz>n)continue;
if(vis[nx][ny][nz] || s[nx][ny][nz]=='*')continue;
vis[nx][ny][nz]=vis[no.x][no.y][no.z]+1;
arr nw;
nw.x=nx,nw.y=ny,nw.z=nz;
q.push(nw);
}
}
}
int main(){
disx[0]=1;disy[0]=0;disz[0]=0;
disx[1]=0;disy[1]=1;disz[1]=0;
disx[2]=0;disy[2]=0;disz[2]=1;
disx[3]=-1;disy[3]=0;disz[3]=0;
disx[4]=0;disy[4]=-1;disz[4]=0;
disx[5]=0;disy[5]=0;disz[5]=-1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
cin>>s[i][j][k];
bfs(1,1,1);
if(vis[n][n][n]==0)puts("-1");
else printf("%d\n",vis[n][n][n]);
return 0;
}
B-[木]迷霧森林
題意:n*m的圖,從左下角走到右上角的全部方案,1不能走,0能走。
題解:常做的題目是從左上走到右下,那個題目的狀態轉移方程爲此題同理,稍微改改就可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int N=2e5+10;
const int Maxn=5e5+10;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
int n,m;
int a[3030][3030];
int p=2333;
int f[3030][3030];
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=read();
f[n][1]=1;
for(int i=n-1;i>=1;i--)
if(a[i][1]==1)break;
else f[i][1]=f[i+1][1]%p;
for(int i=2;i<=m;i++)
if(a[n][i]==1)break;
else f[n][i]=f[n][i-1]%p;
for(int i=n-1;i>=1;i--)
for(int j=2;j<=m;j++)
if(a[i][j]==1)continue;
else f[i][j]=(f[i+1][j]+f[i][j-1])%p;
printf("%d\n",f[1][m]);
return 0;
}
C-小雨坐地鐵
題意:最難的一道題了,題目還挺長的,自己讀讀吧。
題解:自己畫畫圖,會發現其實就是一道求最短路的題目是一道分層最短路+虛點。每次中轉就是當前點到虛點,其花費爲a,其餘就是正常分層建圖即可,然後dis的大小和邊的數量要注意。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int N=2e5+10;
const int Maxn=5e5+10;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
struct Edge{
int to,next,w;
}l[maxn];
struct Node{
int no,dis;
friend bool operator < (Node x,Node y){
return x.dis>y.dis;
}
}a[maxn];
int head[maxn],cnt,cur,dis[maxn];
bool vis[maxn];
priority_queue<Node> q;
void add(int x,int y,int z){
cnt++;
l[cnt].to=y,l[cnt].w=z,l[cnt].next=head[x];
head[x]=cnt;
}
int n,m,S,T;
int main(){
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=1;i<=m;i++){
int a,b,c,pre;
scanf("%d%d%d",&a,&b,&c);
for(int j=1;j<=c;j++){
int x;
scanf("%d",&x);
add((i-1)*n+x,n*m+x,0);
add(n*m+x,(i-1)*n+x,a);
if(j!=1){
add((i-1)*n+pre,(i-1)*n+x,b);
add((i-1)*n+x,(i-1)*n+pre,b);
}
pre=x;
}
}
int s=n*m+S,t=n*m+T;
for(int i=1;i<=n*m+n+n;i++)a[i].dis=INF,a[i].no=i;
a[s].dis=0;cur=s;
q.push(a[s]);
while(!q.empty()){
cur=q.top().no;
q.pop();
if(vis[cur])continue;
vis[cur]=1;
for(int i=head[cur];i;i=l[i].next){
if(a[l[i].to].dis>a[cur].dis+l[i].w){
a[l[i].to].dis=a[cur].dis+l[i].w;
q.push(a[l[i].to]);
}
}
}
if(a[t].dis<INF)printf("%d\n",a[t].dis);
else puts("-1");
return 0;
}
D-表達式求值
題意:給出一個只有+和的算式,求出其值。
題解:C++做法是拿棧做,遇到額外保留一個數即可,不知道爲什麼wa了。所以就用了python。python的話就是一行代碼的事。
print input()%10000
E-suncreen
題意:用n組集合和m組數字,要使得數字儘可能匹配到集合之中。
題解:如果n和m夠大,就需要用到優先隊列了。但是n和m只有2500,排序之後平方暴力即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int N=2e5+10;
const int Maxn=5e5+10;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
struct arr{
int l,r;
friend bool operator < (arr x,arr y){
return x.r<y.r;
}
}cow[3000];
struct brr{
int val,num;
friend bool operator < (brr x,brr y){
return x.val<y.val;
}
}sun[3000];
int n,m;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d%d",&cow[i].l,&cow[i].r);
for(int i=1;i<=m;i++)scanf("%d%d",&sun[i].val,&sun[i].num);
sort(cow+1,cow+1+n);
sort(sun+1,sun+1+m);
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(cow[i].l<=sun[j].val && cow[i].r>=sun[j].val && sun[j].num>0){
ans++;
sun[j].num--;
break;
}
if(sun[j].val>cow[i].r)break;
}
}
printf("%d\n",ans);
return 0;
}