題目
3817,3818,3819
失分小結
估分
100+100+50=250
實際分數
10+100+0=110
這次炸的十分嚴重.
第一題題目看錯……第三題記憶化搜索炸了
題解
T1
P100
我寫的太垃圾了,僅供參考.
CODE
#include<cstdio>
#include<memory.h>
#include<queue>
#define N 1005
using namespace std;
bool mp[N][N],mark[N][N];
int ans[N][N];
char chr[N];
int n,k;
struct node{int x,y;};
queue<node>Q[2];
int rx[]= { 1, 1, 1,-1,-1,-1, 0, 0};
int ry[]= { 1,-1, 0, 1,-1, 0, 1,-1};
int main() {
scanf("%d%d",&n,&k);
for(int i=1; i<=n; i++) {
scanf("%s",chr);
for(int j=1; j<=n; j++)
mp[i][j]=(chr[j-1]=='1');
}
memset(ans,63,sizeof ans);
for(int i=1; i<=n; i++) {
ans[1][i]=ans[n][i]=ans[i][1]=ans[i][n]=0;
Q[1].push((node) {1,i});
Q[1].push((node) {n,i});
Q[1].push((node) {i,1});
Q[1].push((node) {i,n});
}
int f=1;
for(; !Q[f].empty(); f^=1)while(!Q[f].empty()) {
int x=Q[f].front().x,y=Q[f].front().y;
int z=ans[x][y];
Q[f].pop();
if(mark[x][y])continue;
mark[x][y]=1;
for(int i=0; i<8; i++) {
int px=x+rx[i],py=y+ry[i];
if(px<1||px>n||py<1||py>n)continue;
if(mp[px][py]||!mp[x][y]) {
if(ans[px][py]>z) {
ans[px][py]=z;
Q[f].push((node) {px,py});
}
} else {
if(ans[px][py]>z+1) {
ans[px][py]=z+1;
Q[!f].push((node) {px,py});
}
}
}
}
int a,b;
k--;
// for(int i=1; i<=n; i++) {
// for(int j=1; j<=n; j++)
// printf("%d ",ans[i][j]);
// puts("");
// }
scanf("%d%d",&a,&b);
printf("%d",ans[a][b]);
while(k--) {
scanf("%d%d",&a,&b);
printf(" %d",ans[a][b]);
}
puts("");
return 0;
}
T2
這是做的最好的一題…
P100
對於每一種資源,只有第一次出現時(被認爲是稀有資源)和第二次出現時(被認爲是普通資源)有意義,於是可以記錄每種資源第一、二次出現的縱座標,以及上次出現的橫座標。
對於當前資源,
①.若縱座標出現在記錄的第一次之前,則
②.若縱座標出現在記錄第一次之後且在第二次之前,則
這樣會漏了第一、二次出現之間靠近底部的部分,最後加上.
CODE
#include<cstdio>
#define P 19900907
#define N 1105
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
int X1[N*N],Y1[N*N],Y2[N*N];
long long ans=0;
int main() {
int n,m;
scanf("%d %d",&n,&m);
FOR(i,1,n)FOR(j,1,m) {
int k;
scanf("%d",&k);
if(!X1[k]) {
X1[k]=i;
Y2[k]=m+1;
Y1[k]=j;
} else if(j<Y1[k]) {
ans=(ans+1ll*(i-X1[k])*(Y2[k]-Y1[k]))%P;
X1[k]=i;
Y2[k]=Y1[k];
Y1[k]=j;
} else if(j>=Y1[k]&&j<Y2[k]) {
ans=(ans+1ll*(i-X1[k])*(Y2[k]-j))%P;
Y2[k]=j;
}
}
FOR(k,1,n*m)if(X1[k])
ans=(ans+1ll*(n+1-X1[k])*(Y2[k]-Y1[k]))%P;
printf("%lld\n",ans);
return 0;
}
T3
P100
CODE
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#define N 3005
#define M 70005
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
using namespace std;
inline void rd(int &x) {
x=0;static char c;
while(c=getchar(),c<48);
do x=(x<<1)+(x<<3)+(c&15);
while(c=getchar(),c>47);
}
int To[M],Nxt[M],Len[M],Head[N],tot;
struct node {
int x;long long v;
bool operator< (const node &_)const {
return v>_.v;
}
};
int n,m,mark[N],ED[N];
long long dis[N];
vector<int>edge[N];
int main() {
rd(n),rd(m);
memset(dis,-1,sizeof dis);
int st,ed,len;
FOR(i,1,m) {
rd(st),rd(ed),rd(len);
To[++tot]=ed,Nxt[tot]=Head[st],Len[tot]=len,Head[st]=tot;
}
int k,x;
for(int i=1; i<=n; i++) {
rd(k);
mark[i]=k;
for(int j=1; j<=k; j++)rd(x),edge[x].push_back(i);
}
priority_queue<node>Q;
Q.push((node) {1,0});
dis[1]=0;
node tmp;
long long d;
while(!Q.empty()) {
tmp=Q.top();
Q.pop();
x=tmp.x,d=tmp.v;
if(dis[x]!=d)continue;
if(mark[x]) {
ED[x]=1;
continue;
}
if(x==n){
printf("%lld\n",d);
return 0;
}
for(int i=0; i<edge[x].size(); i++) {
int y=edge[x][i];
mark[y]--;
if(mark[y]==0&&ED[y]) {
dis[y]=d;
Q.push((node) {y,d});
}
}
for(int i=Head[x]; i; i=Nxt[i]) {
int y=To[i];
long long t=d+Len[i];
if(dis[y]==-1||dis[y]>t) {
dis[y]=t;
Q.push((node) {y,t});
}
}
}
return 0;
}