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

个人感觉是最短路大冒险……
(不知道为啥中暑了脑子反而活跃了起来,就是代码实现非常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-8

int 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值