NOIP2013提高组复赛day2试题解析
1.

解析:
对于一道题可以先模拟一下他的样例,通过模拟样例发现,总次数正好是每个数与前一个数的差之和,所以就可以得到O(n)复杂度的代码
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+39+7;
ll n,a[N],ans=0;
int main(){
// freopen("block.in","r",stdin);
// freopen("block.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)ans+=(a[i]>a[i-1]?a[i]-a[i-1]:0);
cout<<ans;
return 0;
}
举一反三:
这两道题和本题是一样的
2.

解析:
跟上一道题一样,先模拟数据,通过模拟数据发现,本题可转化为求解整数h1,h2,h3,.....,hn中转折点的个数,就得出代码了
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+39+7;
ll turn=1,h[N],n,ans=0;
int main(){
// freopen("flower.in","r",stdin);
// freopen("flower.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)cin>>h[i];
if(n==1){
cout<<1;
return 0;
}
ans=1;turn=h[1]<=h[2];
for(int i=1;i<=n;i++){
if(i==n&&!turn){
ans++;
continue;
}
if(turn){
if(h[i+1]<h[i]){
turn=0;
ans++;
continue;
}
}else{
if(h[i+1]>h[i]){
turn=1;
ans++;
continue;
}
}
}
cout<<ans;
return 0;
}
3.

解析:
如果使用复杂度为O(n^4)的bfs暴力处理,q一大会TLE,这道题可以转化为spfa求最短路的题目,使用mat数组记录地图,dis记录距离,step记录步数,然后使用O(n^4)的预处理,处理出step数组,
在求解答案时,使用spfa求解最短路,最短路的长度即为答案
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 35+39+7,INF = 0x3f3f3f3f,dx[]={0,0,-1,1},dy[]={-1,1,0,0};
int mat[N][N],dis[N][N][4],step[N][N][4][4],d[N][N],n,m,q,T,ex,ey,sx,sy,tx,ty;
struct node{
int x,y;
};
struct node2{
int x,y,k;
};
bool isok(int x,int y){
return (1<=x&&x<=n&&1<=y&&y<=m);
}
int spfa(){
queue<node2>q;
for(int k=0;k<4;k++){
if(dis[sx][sy][k]!=INF){
q.push((node2){sx,sy,k});
}
}
while(q.size()){
int x=q.front().x,y=q.front().y,k=q.front().k;q.pop();
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(isok(xx,yy)&&mat[xx][yy]&&step[x][y][k][i]!=INF){
if(dis[xx][yy][i^1]>dis[x][y][k]+step[x][y][k][i]+1){
dis[xx][yy][i^1]=dis[x][y][k]+step[x][y][k][i]+1;
q.push((node2){xx,yy,i^1});
}
}
}
}
int ans=INF;
for(int i=0;i<4;i++)ans=min(ans,dis[tx][ty][i]);
return (ans==INF?-1:ans);
}
int bfs(int sx,int sy,int tx,int ty){
if(!mat[sx][sy]||!mat[tx][ty])return INF;
memset(d,0x3f,sizeof(d));
d[sx][sy]=0;
queue<node>q;
q.push((node){sx,sy});
while(q.size()){
if(d[tx][ty]!=INF)return d[tx][ty];
int x=q.front().x,y=q.front().y;
q.pop();
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(isok(xx,yy)&&mat[xx][yy]&&d[xx][yy]==INF){
d[xx][yy]=d[x][y]+1;
q.push((node){xx,yy});
}
}
}
return INF;
}
void init(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int vis=mat[i][j];mat[i][j]=0;
for(int k=0;k<4;k++){
for(int l=0;l<4;l++){
step[i][j][k][l]=bfs(i+dx[k],j+dy[k],i+dx[l],j+dy[l]);
}
}
mat[i][j]=vis;
}
}
}
int solve(){
cin>>ex>>ey>>sx>>sy>>tx>>ty;
if(sx==tx&&sy==ty)return 0;
if(sx==ex&&sy==ey)return -1;
if(!isok(ex,ey)||!isok(sx,sy)||!isok(tx,ty))return -1;
if(!mat[ex][ey]||!mat[sx][sy]||!mat[tx][ty])return -1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<4;k++){
dis[i][j][k]=INF;
}
}
}
mat[sx][sy]=0;
for(int k=0;k<4;k++)dis[sx][sy][k]=bfs(ex,ey,sx+dx[k],sy+dy[k]);
mat[sx][sy]=1;
return spfa();
}
int main(){
cin>>n>>m>>T;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>mat[i][j];
}
}
init();
while(T--)
cout<<solve()<<'\n';
return 0;
}

浙公网安备 33010602011771号