严重感觉出题人脑子有问题。。。前两题几乎一毛一样。。都是找峰和谷。。200分轻松拿下。。加上第一题的260貌似已经够大浙江的一等线了、、。第三题看着感觉很麻烦。。。似乎爆搜拿不到几分。。。加上上午要去看sdl比赛。。。只打了一个多小时(day1不过打了2个小时) 所以就抱着玩一下的心态写了一个骗分,,顺利拿到5分。。。
1刚刚说了找峰和谷然后自己找规律乱搞了一下加加减减。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
long long high,low;
long long a[100005];
void feng()
{
for(int i=1;i<=n;i++)
if(a[i]>a[i+1]&&a[i]>=a[i-1]) high=high+a[i];
}
void gu()
{ for(int i=1;i<=n;i++)
if(a[i]<=a[i+1]&&a[i]<a[i-1]) low=low+a[i];
}
int main()
{
freopen("block.in","r",stdin);
freopen("block.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
{scanf("%d",&a[i]);
}
feng();
gu();
cout<<high-low;
return 0;
}
2.还是峰和谷,,,
#include <cstdio>
#include<iostream>
#include <cstring>
using namespace std;
bool pd[100002];
int a[100002];
int main()
{freopen("flower.in","r",stdin);
freopen("flower.out","w",stdout);
int n,i,l,r,tot=0;
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
l=i-1;
r=i+1;
while (pd[l]) l--;
while (pd[r]) r++;
if ((l!=0) && (r!=n+1) && ((a[l]<=a[i] && a[i]<=a[r]) || (a[l]>=a[i] && a[i]>=a[r]))) pd[i]=true;
}
for (i=1;i<=n;i++) if (!pd[i]) tot++;
printf("%d",tot);
return 0;
}
3。。先来看一下敷衍的5分程序。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m,q;
int a[100][100];
int x,y,x2,y2,x3,y3;
int main()
{
freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{scanf("%d",&a[i][j]);
}
cin>>x>>y>>x2>>y2>>x3>>y3;
if(x2==x3&&y2==y3) {cout<<0;return 0; }
if(abs(x2-x3)+abs(y2-y3)==1&&x==x3&&y==y3) {cout<<1; return 0;}
cout<<-1;
return 0;
}
好了我们来说一下标算吧。。。感觉比赛的时候完全想不到。。。
预处理部分:
因为对棋子的移动最终对应着对空格的移动,而空格的初始位置(非起始情况)一定是在目标棋子的上下左右的。
这样我们把空格先准备好,然后移动一下棋子,这种操作的代价很容易发现是常数。因此可以使用最短路。方法是把每个棋子一分为四,上下左右,[一个棋子的左边]就代表了空格的初始位置在这个棋子的左边,即它前一次是从左边移过来的。每个棋子的每一边可以建立于上面棋子的下边,下面棋子的上边等的联系(用一个有向图来存储),并存储价值。
最后还有一个小问题,就是每次的q的空白位置不是在目标棋子的上下左右。这时候选择目标棋子的一类,并且修改其与周遭棋子联系的边权,然后做最短路,然后记得要改回去。
最短路用dijk也可以a#include<stdio.h>
#include<queue>
#include<vector>
#include<string.h>
#include<iostream>
using namespace std;
typedef pair<int,int> pii;
queue<pii>Q;
const int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int way[40][40][10],cnt[10],dist[40][40],val[10010];
int woc[4]= {1,0,3,2};
int V,S,T,sx1,sy1,sx2,sy2,sx3,sy3,st[10000];
int map[40][40];
struct sugar
{
int u,v,next;
}a[100010];
int m,n,q,tot;
void add(int i,int j,int k)
{
a[++tot].u = k;
a[tot].v = j;
a[tot].next = st[i];
st[i] = tot;
}
int bfs(int sx1,int sy1,int sx2,int sy2)
{
if(sx1 == sx2 && sy1 == sy2) return 0;
while(!Q.empty()) Q.pop();//检查
memset(dist,0x3f,sizeof(dist));
dist[sx1][sy1] = 0;
Q.push(make_pair(sx1,sy1));
while(!Q.empty())
{
pii u = Q.front();
Q.pop();
for(int k = 0 ; k <= 3 ; k++)
{
if(dist[u.first + dir[k][0]][u.second + dir[k][1]] && dist[u.first + dir[k][0]][u.second+dir[k][1]]==dist[39][39] && map[u.first+dir[k][0]][u.second+dir[k][1]])
{
dist[u.first + dir[k][0]][u.second + dir[k][1]] = dist[u.first][u.second] + 1;
if(u.first + dir[k][0] == sx2 && u.second + dir[k][1] == sy2) return dist[u.first][u.second] + 1;
Q.push(make_pair(u.first + dir[k][0],u.second + dir[k][1]));
}
}
}
return dist[39][39];
}
void check()
{
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
for(int k = 0 ; k <= 3 ; k++)
if(map[i + dir[k][0]][j + dir[k][1]] && map[i][j])
add(way[i][j][k],way[i+dir[k][0]][j+dir[k][1]][woc[k]],1);
}
int spfa(int S,int T)
{
int que[10010],p[10010],f=1,l=1;
memset(p,0,sizeof(p));
memset(que,0,sizeof(que));
memset(val,0x3f,sizeof(val));//111111 63
val[S] = 0;que[1] = S;p[S] = 1;
while(f <= l)
{
int j = que[f++];
p[j] = 0;
for(int i = st[j] ; i != 0 ; i = a[i].next)
{
if(a[i].u + val[j] < val[a[i].v])
{ val[a[i].v] = a[i].u + val[j];
if(!p[a[i].v]) que[++l] = a[i].v,p[a[i].v] = 1;
}
}
}
return val[T];
}
void output()
{
for(int i = 1 ; i <= q ; i++)
{scanf("%d%d%d%d%d%d",&sx1,&sy1,&sx2,&sy2,&sx3,&sy3);
if(map[sx2][sy2] == 0 || map[sx3][sy3] == 0 ){printf("-1\n");continue;}
if(sx2 == sx3 && sy2 == sy3) {printf("0\n");continue;}
map[sx2][sy2] = 0;
for(int j = 0 ; j <= 3 ; j++)
if(map[sx2+dir[j][0]][sy2+dir[j][1]])
cnt[j] = bfs(sx1,sy1,sx2+dir[j][0],sy2+dir[j][1]);
map[sx2][sy2] = 1;
T = ++V;
for(int j = 0 ; j <= 3 ; j++)
if(map[sx3 + dir[j][0]][sy3 + dir[j][1]] == 1)
add(way[sx3][sy3][j],T,0);
S = ++V;
for(int j = 0 ; j <= 3 ; j++)
if(map[sx2 + dir[j][0]][sy2 + dir[j][1]])
add(S,way[sx2][sy2][j],cnt[j]);
int ans = spfa(S,T);
if(ans >= 1061109567) printf("-1\n");
else printf("%d\n",ans);
}
}
int main()
{freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
scanf("%d%d%d",&n,&m,&q);
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
scanf("%d",map[i]+j);
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
for(int k = 0 ; k <= 3 ; k++)
way[i][j][k] = ++V;// 方向
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
{
if(map[i][j])
{ map[i][j] = 0;
for(int k = 0 ; k <= 3 ; k++)
{
if(map[i+dir[k][0]][j+dir[k][1]])
{ for(int o = 0 ; o <= 3 ; o++)
{
if(o != k && map[i+dir[o][0]][j+dir[o][1]])
add(way[i][j][k],way[i][j][o],bfs(i+dir[k][0],j+dir[k][1],i+dir[o][0],j+dir[o][1]));
}
}
}
map[i][j] = 1;
}
}
check();
output();
return 0;
}