码迷,mamicode.com
首页 > 其他好文 > 详细

2018.10.02 练习赛

时间:2018-10-03 00:38:45      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:lsp   etc   algo   tchar   \n   art   sdi   iostream   练习   

[T1 蒜头君当大厨]

题解:

显然差分约束,怕你看不出样例还疯狂暗示你= =

\(code\):

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<ctype.h>
#define ll long long 
using namespace std;

char buf[1<<20],*p1,*p2;
inline char gc()
{
//  return getchar();
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}

template<typename T>
inline void read(T &x)
{
    char tt;
    bool flag=0;
    while(!isdigit(tt=gc())&&tt!='-');
    tt=='-'?(flag=1,x=0):(x=tt-'0');
    while(isdigit(tt=gc())) x=x*10+tt-'0';
    if(flag) x=-x;
}

struct node{
    ll x,len;
    inline node(ll a=0,ll b=0)
    {
        x=a;
        len=b; 
    }
    inline bool operator<(node a)const
    {
        return len<a.len;
    }
};

queue<ll>q;
vector<node>G[20005];
ll n,m,dis[20005],tot[20005];
bool book[20005];

int spfa(int s) {
    for(int i=1; i<=n; i++) dis[i]=-1,book[i]=false;
    dis[s]=0,q.push(s),book[s]=true,tot[s]++;
    while (!q.empty()) {
        ll x=q.front();
        q.pop(),book[x]=false;
        if(tot[x]==n+1) return -1;
        for (int i=G[x].size()-1; i>=0; i--) {
            ll p=G[x][i].x;
            ll len=G[x][i].len;
            if(dis[p]>=dis[x]+len) continue;
            dis[p]=dis[x]+len;
            if(book[p]) continue;
            q.push(p),book[p]=true,tot[p]++;
        }
    }
    return 1;
}

int main()
{
    read(n),read(m);
    for(ll i=1;i<=n;i++)
    G[0].push_back(node(i,0));
    for(int i=1;i<=m;i++)
    {
        ll op,x,y,z;
        read(op);
        if(op<=2) read(x),read(y),read(z);
        if(op>=3) read(x),read(z);
        if(op==1) G[x].push_back(node(y,z));
        if(op==2) G[y].push_back(node(x,z));
        if(op==3) G[0].push_back(node(x,z));
        if(op==4) G[x].push_back(node(0,-z));
    }
    ll ans=0;
    if(spfa(0)==-1) puts("I can't"),exit(0);
    for(int i=1;i<=n;i++)
    ans=max(ans,dis[i]);
    printf("%lld",ans); 
}

[T2 上课]

题解:

贪心预处理出\(g[i]\),表示能力为\(i\)时最早的时刻为多少,然后就类似背包一样的\(DP\)

\(code:\)

#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<ctype.h>
#define ll long long
#define inf 1e9+9
using namespace std;

char buf[1<<20],*p1,*p2;
inline char gc()
{
//  return getchar();
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}

template<typename T>
inline void read(T &x)
{
    char tt;
    bool flag=0;
    while(!isdigit(tt=gc())&&tt!='-');
    tt=='-'?(flag=1,x=0):(x=tt-'0');
    while(isdigit(tt=gc())) x=x*10+tt-'0';
    if(flag) x=-x;
}

struct node{
    int t,len,x;
    inline node(int a=0,int b=0,int c=0)
    {
        t=a;
        len=b;
        x=c;
    }
    inline bool operator<(node a) const
    {
        return t<a.t;
    }
}a[1005];

int t,m,n;
int f[1005],g[105];
int main()
{
    read(t),read(m),read(n);
    for(int i=1;i<=m+1;i++) f[i]=-inf;
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        read(x),read(y),read(z);
        a[i]=node(x,y,z);
    }
    
    a[0].x=1,a[0].len=0,a[0].t=1,a[m+1].t=t+1;
    sort(a+1,a+1+m);
    
    for(int i=0;i<=100;i++) g[i]=inf;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        read(x),read(y);
        g[y]=min(g[y],x);
    }
    
    for(int i=1;i<=100;i++) g[i]=min(g[i],g[i-1]);
    
    for(int i=1;i<=m+1;i++)
    for(int j=0;j<i;j++)
    f[i]=max(f[i],f[j]+(a[i].t-(a[j].t+a[j].len))/g[a[j].x]);
    
    printf("%d",f[m+1]);
}

[T3 营救]

题解:

说实话思路很简单,但是但代码实现能力对我来说是硬伤啊\(......\)正解\(BFS+\)三进制状压\(DP\),略恶心

\(code:\)

#include<stdio.h>
#include<iostream> 
#include<math.h>
#include<string.h> 
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define inf 1e9+9
using namespace std;

struct point{
    int x,y;
    inline point(int a=0,int b=0)
    {
        x=a;
        y=b;
    }
}start,end_;


struct node{
    int x,y,s;
    inline node(int a=0,int b=0,int c=0)
    {
        x=a;
        y=b;
        s=c;
    }
    inline node(point a,int b=0)
    {
        x=a.x;
        y=a.y;
        s=b;
    } 
};

int n,m,k,ans=inf,tot;
int val[11];
char a[11][11],ss[11];
int f[200005][11][11];
int s[20];
queue<node>q;
int quanji;
int calspd(int num)
{
    int len=0,sum=k;
    memset(s,0,sizeof(s));
    while(num)
    {
        s[++len]=num%3;
        num/=3;
    }
    for(int i=1;i<=tot;i++)
    sum+=(s[i]==1)?val[i]:0;
    return sum<1?1:sum;
}

int merge(int num,int x,int y)
{
    int len=0,sum=0;
    memset(s,0,sizeof(s));
    while(num)
    {
        s[++len]=num%3;
        num/=3;
    }
    int flag=0;
    for(int i=1;i<=tot;i++)
    if(ss[i]==a[x][y]) flag=i;
    if(s[flag]) return 0;
    s[flag]=1;
    for(int i=tot;i>=1;i--)
    sum=sum*3+s[i];
    return sum;
}

int drop1(int num)//放下减速的 
{
    int len=0,sum=0;
    memset(s,0,sizeof(s));
    while(num)
    {
        s[++len]=num%3;
        num/=3;
    }
    for(int i=1;i<=tot;i++)
    if(s[i]==1&&val[i]>0) s[i]=2;
    for(int i=tot;i>=1;i--)
    sum=sum*3+s[i];
    return sum;
}

int drop2(int num)//全放下 
{
    int len=0,sum=0;
    memset(s,0,sizeof(s));
    while(num)
    {
        s[++len]=num%3;
        num/=3;
    }
    for(int i=1;i<=tot;i++)
    if(s[i]) s[i]=2;
    for(int i=tot;i>=1;i--)
    sum=sum*3+s[i];
    return sum;
}

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        char tt; 
        scanf("\n%c",&tt);
        if(tt=='s') start=point(i,j);
        if(tt=='#') a[i][j]='#';
        if(tt=='t') end_=point(i,j);
        if(tt>='A'&&tt<='Z') a[i][j]=tt,tot++;
    }
    quanji=pow(3,tot)-1;
    for(int i=1;i<=tot;i++)
    {
        char tt;
        int x;
        scanf("\n%c%d",&tt,&x);
        ss[i]=tt;
        val[tt-'A'+1]=x;
    }
//  printf("%d %d %d",drop1(3),drop2(3),merge(3,3,3));
    
    for(int i=0;i<=quanji;i++)
    for(int j=1;j<=10;j++)
    for(int z=1;z<=10;z++)
    f[i][j][z]=inf;
    f[0][start.x][start.y]=0;
    
    q.push(node(start,0));
    while(!q.empty())
    {
        int tx=q.front().x,ty=q.front().y,ts=q.front().s;
        q.pop();
        int spd=calspd(ts);
        if(tx+1<=n&&a[tx+1][ty]!='#'&&f[ts][tx+1][ty]>f[ts][tx][ty]+spd)//下 
        {
            f[ts][tx+1][ty]=f[ts][tx][ty]+spd; 
            q.push(node(tx+1,ty,ts));
        }
        if(ty+1<=m&&a[tx][ty+1]!='#'&&f[ts][tx][ty+1]>f[ts][tx][ty]+spd)//右
        {
            f[ts][tx][ty+1]=f[ts][tx][ty]+spd;
            q.push(node(tx,ty+1,ts));
        } 
        if(tx-1>0&&a[tx-1][ty]!='#'&&f[ts][tx-1][ty]>f[ts][tx][ty]+spd)//上 
        {
            f[ts][tx-1][ty]=f[ts][tx][ty]+spd;
            q.push(node(tx-1,ty,ts));
        } 
        if(ty-1>0&&a[tx][ty-1]!='#'&&f[ts][tx][ty-1]>f[ts][tx][ty]+spd)//左
        {
            f[ts][tx][ty-1]=f[ts][tx][ty]+spd;
            q.push(node(tx,ty-1,ts));
        } 
        if(a[tx][ty]>='A'&&a[tx][ty]<='Z')//合并
        {
            int newset=merge(ts,tx,ty);
            if(!newset||f[newset][tx][ty]<=f[ts][tx][ty]) continue;
            f[newset][tx][ty]=f[ts][tx][ty];
            q.push(node(tx,ty,newset));
        } 
        if(tx==end_.x&&ty==end_.y)//放下
        {
            int new1=drop1(ts),new2=drop2(ts);
            if(f[new1][tx][ty]>f[ts][tx][ty])
            {
                f[new1][tx][ty]=f[ts][tx][ty];
                q.push(node(tx,ty,new1));
            }
            
            if(f[new2][tx][ty]>f[ts][tx][ty])
            {
                f[new2][tx][ty]=f[ts][tx][ty];
                q.push(node(tx,ty,new2));
            }
        } 
    }
    printf("%d",f[quanji][end_.x][end_.y]);
}

2018.10.02 练习赛

标签:lsp   etc   algo   tchar   \n   art   sdi   iostream   练习   

原文地址:https://www.cnblogs.com/KatouKatou/p/9738736.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!