(补题心路)福州大学第十四届程序设计竞赛_重现赛

来源:互联网 发布:淘宝导航条两边颜色 编辑:程序博客网 时间:2024/06/08 12:27

个人感觉是最短路大冒险……
(不知道为啥中暑了脑子反而活跃了起来,就是代码实现非常gg)


fzu 2253 Salty Fish
渔夫翻咸鱼,会把一个区间里的1翻成0 0翻成1
区间长度至少为1
问最多有几个1

统计原先的咸鱼数量
考虑每翻一次,如果本来是1 会使咸鱼数量-1,如果本来是0,会使咸鱼数量+1
所以把数组更改为-1 +1
即数组变为翻该鱼会对总鱼数的影响
然后求一个最大连续子序列和
最大值(翻身影响)+原来的鱼数=最大鱼数
但是因为至少要翻一条鱼
所以特殊情况就是明明本来都是翻身的咸鱼,还一定要-1

#include <cstring>#include <cmath>#include <cstdio>#include <iostream>using namespace std;const int maxn=100010;#define eps 1e-8int s[maxn],a[maxn];int main(){int cases,i,j,ans,cnt,now,maxx,n; while (~scanf("%d",&n))   {    ans=0; cnt=0; now=0;    memset(s,0,sizeof(s));     for (i=1;i<=n;i++)         {            scanf("%d",&a[i]);            if (a[i]) ans++;            if (i==1 || a[i]!=a[i-1]) cnt++;         if (a[i]==0) s[cnt]++; else s[cnt]-=1;         }             maxx=0;    for (i=1;i<=cnt;i++)     {     if (now+s[i]>0)  now+=s[i]; else now=0;     maxx=max(maxx,now);     }    if (maxx)   printf("%d\n",ans+maxx); else printf("%d\n",ans-1);   }   return 0;}

fzu 2254 英语考试

比赛的时候……用了各种姿势
最短路 拓扑 wa的死去活来
……后来发现最短路能ac 但是我忘记初始化了……

最短路能ac,但总感觉怪怪的

每个单词一定存在的一种花费是len
或者从已经背诵的单词转移过来,需要的花费是hamming(Si, T) * w

用最短路的思路去更新,先记录各个单词之间转移需要的花费
每次找需要花费最少的单词进行背诵,然后更新未被背诵的单词

#include <iostream>#include <cstdio>#include <vector>#include <string>#include <cstring>#include <map>#include <queue>#include <algorithm>#include <stack>using namespace std;const int maxn=1010;const int INF=0x3f3f3f3f;int len;int n,mar[maxn][maxn],fin[maxn],dis[maxn];int ind[maxn],vis[maxn];vector<int>G[maxn];void Dijkstr(int source){    memset(fin,0,sizeof(fin));    int i,j,minx,nextp;    for (i=1;i<=n;i++)    {        fin[i]=0;        dis[i]=mar[source][i];    }    fin[source]=1;    dis[source]=0;    for (i=2;i<=n;i++)    {        minx=INF;        for (j=1;j<=n;j++)            if (fin[j]==0 && dis[j]<minx)            {                minx=dis[j];                nextp=j;            }        if (minx==INF) return;        fin[nextp]=1;        for (j=1;j<=n;j++)            if (fin[j]==0 && mar[nextp][j]<dis[j])                dis[j]=mar[nextp][j];    }}char ss[maxn][15];int main(){    int cases,m,u,v,w,sum,minn,mini;    while (~scanf("%d%d%d",&n,&len,&w))    {        for (int i=1;i<=n;i++)            {                scanf("%s",ss[i]);                G[i].clear();                dis[i]=len;            }            memset(mar,0,sizeof(mar));      minn=len; mini=1;        for (int i=1;i<n;i++)            for (int j=i+1;j<=n;j++)            {                mar[i][j]=len; sum=0;                for (int k=0;k<len;k++)                    if (ss[i][k]!=ss[j][k]) sum+=w;                if (sum<len) mar[i][j]=sum;                mar[j][i]=mar[i][j];                if (mar[i][j]<minn) {mini=i; minn=mar[i][j]; }            }     Dijkstr(mini);     sum=len;     for (int i=1;i<=n;i++) sum+=dis[i];     printf("%d\n",sum);    }    return 0;}

过河


fzu 2256 迷宫
一棵树
n个点

接下来n-1行,第i行包含两个数字Pi和Wi,表示i+1号房间的上级房间为Pi,道路长度为Wi。
子节点和父节点之间的路是wi
也就是说任意两点光靠走路其实都是相通的
每个房间拥有一个时空传送门,第i个房间的传送门可以花费Di单位的时间传送到它的任意一个下级房间中(如果x是y的下级房间,并且y是z的下级房间,那么x也是z的下级房间)
这里意味着父节点都有传送阵,可以传送到任意子节点。
所以考虑把利用dfs把子节点都传递上来,建边,花费d[i]
跑个最短路……输出

比赛的时候疯狂mle是因为模板里有个判断负环的数组没删QAQ(这样也行嘛)

#include <iostream>#include <cstdio>#include <vector>#include <string>#include <cstring>#include <map>#include <queue>#include <algorithm>#include <stack>using namespace std;const int maxn=100010;const int INF=0x3f3f3f3f;int dis[maxn],inq[maxn];int n,d[maxn];struct points{int v,w;};vector<points>G[maxn];vector<int>son[maxn];void add_edge(int u,int v,int w){points now;now.v=v;now.w=w;G[u].push_back(now);}void SPFA(int source){  int u,v,w,i;  memset(inq,0,sizeof(inq));  for (i=0;i<=n+1;i++) dis[i]=INF;    dis[source]=0;    inq[source]=1;  queue<int>q;  points now;  q.push(source);  while (!q.empty())  {    u=q.front(); q.pop();    inq[u]=0;    for (i=0;i<G[u].size();i++)    {      v=G[u][i].v;      w=G[u][i].w;      if (dis[v]>dis[u]+w)      {        dis[v]=dis[u]+w;        if (!inq[v])        {          inq[v]=1;          q.push(v);        }      }    }  }  return;}void dfs(int now){int v,vv;for (int i=0;i<son[now].size();i++){dfs(son[now][i]);}int xx=son[now].size();for (int i=0;i<xx;i++){ v=son[now][i];for (int j=0;j<son[v].size();j++){vv=son[v][j];son[now].push_back(vv);add_edge(now,vv,d[now]);}}return;}int main(){int cases,m,u,v,w,S;while (~scanf("%d",&n)){    for (int i=1;i<=n;i++) { scanf("%d",&d[i]); G[i].clear(); son[i].clear();}    for (int i=2;i<=n;i++)    {        scanf("%d%d",&u,&w);        son[u].push_back(i);        if (w<d[u]) add_edge(u,i,w); else add_edge(u,i,d[u]);    }    dfs(1);    SPFA(1);        for (int i=1;i<=n;i++) printf("%d ",dis[i]);        printf("\n");}    return 0;}

Saya的小熊饼干
dalao说是原题。。。http://acm.hdu.edu.cn/showproblem.php?pid=5245


fzu 2258 奖励
不能用除法……判断总分>=240且单科都>=60就好了。



Card Game


浪里个浪
多起点多终点最短路
把所有可能的起点和零点建边,路程为0
把所有可能的终点和n+1点建边,路程为0
跑一遍从0点开始的最短路,输出到n+1这个点的最短路程
和hdu 2066类似
不过因为hdu那题数据小,……我跑了s遍最短路……emmmmm

阅读全文
1 0
原创粉丝点击