-TEST 13 for NOIP 。。。(210/300)

头更更大

这个10月完就要去搞NOIP了。。。

10月30天也就3次测试。。。为保佑进省一我还是每次测试玩都写个总结。。


好不容易没有炸一次orz。发挥最正常的一次。
第一题一开始卡了我接近一个小时。。然后发现这一个小时卡值了因为第一题没有爆掉。。而且运气好(?)Linux没有卡掉我的gets()。。。
第二题又是直接把Dijkstra魔改了一下就砸了上去,(大锤)80,错的都是TLE。
第三题玄学。。。没有推出树形Dp乱打了一个竟然过了30分。。。
总之发挥正常。

不行之前的太水了我重新写一遍
下面面详细解答:

T1(100/100):抄代码

problem

题意:每组数据给出两个字符串,问你第二个字符串能不能通过对第一个字符串进行一些操作而得到。操作是:每次把字符串中的一种小写字母全部换为另一种小写字母。
样例

  • 输入
    5
    int x;
    int y;
    double a;
    double aa;
    float 1
    float 2
    string s;
    double d;
    print thisismycode;
    float tooooooooooo;

  • 输出
    1
    0
    0
    1
    1

solution

鉴于曾老曾说过如果打完了最好丢进Linux虚拟机看一下有没有问题,很多人打了gets然后被虚拟机说危险不准编译(别问我为什么我就直接打的gets()),于是各种魔改输入然后各种GG。也有很多人判错了或者判漏了。
事实上凯爷也有疏忽的时候:

abcdefghijklmnopqrstuvwxyz
zyxwvutsrqponmlkjihgfedcba

按照题意上面这组数据应该是没法换的。然而凯爷的程序的解是1。。
不听不听王八念经
然后http://blog.csdn.net/hcu5555/article/details/20555229给出了专门取代gets()的代码,亲测有用!!

T2(80/100):做运动

problem

题意:有个人想在一个有向图上跑步减肥,询问你在保证经过的路径的最大的权值1最小的情况下的最短路长度。
每条边的长度是第一个权(每行第三个数据)和第二个权(每行第四个数据)的乘积。
样例

  • 输入
    5 6
    1 2 1 2
    2 3 2 2
    3 4 3 4
    4 5 3 5
    1 3 4 1
    3 5 3 6
    1 5

  • 输出
    3 24

solution

80%的暴力Dijkstra往上套就行了。
不过优先队列要多加一个关键字,以温度为第一关键字,热量为第二关键字,序号为第三关键字建立小跟堆。
100%的正解是用并查集优化。
先对边进行排序,每加一个边判断一次起点终点是否连通。连通后继续加边直到加入的下一条边的边权大于目前图中最大边权,最后跑Dijkstra。

T3(30/100):大逃杀

problem

题意
。。。不好描述看后面。
样例

  • 输入 
    17 54
    5 5 1 1 1 25 1 10 15 3 6 6 66 4 4 4 4
    0 1 3 0 0 0 1 3 2 0 6 7 54 0 0 0 0
    1 8 3
    2 8 3
    8 7 7
    7 13 0
    7 14 0
    15 14 2
    16 14 3
    17 14 5
    7 9 4
    9 10 25
    10 11 0
    10 12 0
    7 6 20
    3 6 3
    3 4 3
    3 5 3

  • 输出
    68

solution

一开始不知道我哪根筋抽了想搞状压Dp。。。
30%随便乱搞一个树形Dp水过。。。
100%的还是凯爷大佬刁orz。。又学会了树形Dp套路。

感想

多玩洛谷!多练Dp!!多练模板!!!

代码:

T1:

my/std.cpp

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

#define U_MAX 2000
char *get_str(char *str)
{
    fgets(str,U_MAX,stdin);
    if(str[strlen(str)-1] == '\n')
       str[strlen(str)-1] = '\0';
    return str;
}

inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}

int T,s1,t1;
char s[2005];
char t[2005];
int loc[30];

bool jud(char c){return (c>='a'&&c<='z')?(true):(false);}

int main()
{
    T=read();
    while(T--)
    {
        int i=0,ans=0,cnt=1;
        memset(loc,0,sizeof(loc));  
        get_str(s);s1=strlen(s);
        get_str(t);t1=strlen(t);
        if(s1==t1)
        for(i=0;i<s1;i++)
        {           
            if(!jud(s[i]))
            {
                if(!jud(t[i]))
                {
                    if(s[i]!=t[i]){cnt=0;break;}
                }
                else {cnt=0;break;}
            }
            if(jud(s[i])&&jud(t[i]))
            {           
                if(!loc[s[i]-'a'+1])loc[s[i]-'a'+1]=t[i]-'a'+1;
                else if(loc[s[i]-'a'+1]!=t[i]-'a'+1){cnt=0;break;}
            }
        }
        else cnt=0;
        if(i==s1&&cnt)ans=1;
        cout << ans << endl;
    }
    return 0;
}

T2

my/std.cpp

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}

const int kkk=500050;
int n,m,u,v,t,c;

int first[kkk],cnt=0;
struct node{
    int u,v,t,next;
    long long val;  
}side[4*kkk];

struct edoe{
    int u,v,t,c;
    friend inline bool operator < (const edoe &a,const edoe &b)
    {return a.t<b.t;}   
}edge[2*kkk];

inline void add(int u,int v,int t,int c)
{
    side[++cnt].u=u;
    side[cnt].v=v;
    side[cnt].t=t;
    side[cnt].val=1ll*c*t;
    side[cnt].next=first[u];
    first[u]=cnt;
}

priority_queue< pair<long long,int> >que;
bool vis[kkk];
long long dis[kkk];
int tem[kkk];

int s1,s[5],x1,x[5];
inline void dij()
{
    memset(dis,127,sizeof(dis));
    memset(tem,127,sizeof(tem));    
    for(int i=1;i<=s1;i++)
    {
        dis[s[i]]=0;
        tem[s[i]]=0;
        vis[s[i]]=true;     
        que.push(make_pair(0,s[i]));    
    }
    while(!que.empty())
    {
        u=que.top().second;que.pop();vis[u]=false;
        for(int i=first[u];i;i=side[i].next)
        {
            v=side[i].v;    
            if(dis[v]>dis[u]+side[i].val)
                if(!vis[v])
                {
                    dis[v]=dis[u]+side[i].val;
                    que.push(make_pair(-dis[v],v)); 
                }
        }
    }
}

int fa[kkk];
inline int ga(int x){return((fa[x]==x)?(x):(fa[x]=ga(fa[x])));}

int main()
{
    n=read();m=read();
    for(register int i=1;i<=m;i++)
    {
        edge[i].u=read();
        edge[i].v=read();
        edge[i].t=read();
        edge[i].c=read();
        fa[edge[i].u]=edge[i].u; 
        fa[edge[i].v]=edge[i].v;
    }
    sort(edge+1,edge+m+1);

    int tot=0,max_temp=0;

    s1=1;   s[1]=read();
    x1=1;   x[1]=read();    

    while(!(ga(s[s1])==ga(x[x1])&&edge[tot+1].t>edge[tot].t))
    {
        tot++;
        max_temp=max(max_temp,edge[tot].t);
        u = edge[tot].u;
        v = edge[tot].v;
        t = edge[tot].t;
        c = edge[tot].c;
        add(u,v,t,c);add(v,u,t,c);
        if(ga(u)!=ga(v))fa[ga(v)]=ga(u);
    }

    dij();
    for(int i=1;i<=x1;i++)cout<<max_temp<<" "<<dis[x[i]]<<endl;
    return 0;
}

T3

这里写图片描述

std.cpp

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
int read()
{
    int f=1,i=0;char ch=getchar();
    while(ch<'0'||ch>'9') 
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        i=(i<<3)+(i<<1)+ch-'0';
        ch=getchar();
    }
    return f*i;
}
struct node{int v,w,next;}side[305<<1];
int n,k,x,y,z,cnt;
int tmp[305],f[305][305][3],t[305],w[305],first[305];
bool vis[305];
inline void add(int x,int y,int z)
{
    side[++cnt].next=first[x];
    first[x]=cnt;
    side[cnt].v=y;side[cnt].w=z;
}
inline void dfs(int u)
{
    vis[u]=true;
    for(int i=t[u];i<=k;++i) f[u][i][0]=f[u][i][1]=f[u][i][2]=w[u];
    for(int e=first[u];e;e=side[e].next)
    {
        int v=side[e].v;
        if(!vis[v])
        {
            dfs(v); 
            for(int i=0;i<=k;++i) tmp[i]=f[u][i][2];
            for(int j=0;j<=k;++j)
            {
                for(int i=2*side[e].w+t[u]+j;i<=k;++i)
                    tmp[i]=max(tmp[i],f[u][i-2*side[e].w-j][2]+f[v][j][0]);

                for(int i=2*side[e].w+t[u]+j;i<=k;++i)
                    tmp[i]=max(tmp[i],f[u][i-2*side[e].w-j][0]+f[v][j][2]);

                for(int i=side[e].w+t[u]+j;i<=k;++i)
                    tmp[i]=max(tmp[i],f[u][i-side[e].w-j][1]+f[v][j][1]);
            }
            for(int i=0;i<=k;++i) f[u][i][2]=tmp[i];//两边都不回头

            for(int i=0;i<=k;++i) tmp[i]=f[u][i][1];
            for(int j=0;j<=k;++j)
            {
                for(int i=2*side[e].w+t[u]+j;i<=k;++i)
                    tmp[i]=max(tmp[i],f[u][i-2*side[e].w-j][1]+f[v][j][0]);

                for(int i=side[e].w+t[u]+j;i<=k;++i)
                    tmp[i]=max(tmp[i],f[u][i-side[e].w-j][0]+f[v][j][1]);
            }
            for(int i=0;i<=k;++i) f[u][i][1]=tmp[i];//一边回头一边不回 

            for(int i=0;i<=k;++i) tmp[i]=f[u][i][0];
            for(int j=0;j<=k;++j)
            {
                for(int i=2*side[e].w+t[u]+j;i<=k;++i)
                    tmp[i]=max(tmp[i],f[u][i-2*side[e].w-j][0]+f[v][j][0]);
            }
            for(int i=0;i<=k;++i) f[u][i][0]=tmp[i];//都回头 
        }
    }
}
int main()
{

    n=read();k=read();
    for(int i=1;i<=n;++i) w[i]=read();
    for(int i=1;i<=n;++i) t[i]=read();
    for(int i=1;i<n;++i)
    {
        x=read(),y=read(),z=read();
        add(x,y,z),add(y,x,z);
    }
    dfs(1);
    int ans=0;
    for(int i=1;i<=n;++i)
        for(int j=0;j<=k;++j)
            for(int l=0;l<3;++l) ans=max(ans,f[i][j][l]);
    cout<<ans<<endl;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值