2018个人PK赛#5

2018-01-20

 
两层循环
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>

typedef long long ll;
using namespace std;
const int MOD=1e9+7;
int main()
{
    int n,a,b,c,maxx=0;
    scanf("%d%d%d%d",&n,&a,&b,&c);
    for(int i=0;i<=n/a;i++)
        for(int j=0;j<=n/b;j++)
            if((n-a*i-b*j)>=0&&(n-a*i-b*j)%c==0)
            {
                maxx=max(maxx,i+j+(n-a*i-b*j)/c);
            }
    printf("%d\n",maxx);
    return 0;
}
View Code

B - s-palindrome

CodeForces - 691B

判断该字符串是否是镜像的,模拟 注意‘n’,‘m’并不镜像

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>

typedef long long ll;
using namespace std;
const int MOD=1e9+7;
char str[]={'A','H','I','M','O','o','T','U','V','v','W','w','X','x','Y'};
const int N=1e3+7;
char ch[N];
int path(char c)
{
    for(int i=0;i<15;i++)
        if(c==str[i])
            return 1;
    return 0;
}
int lp(char c,char d)
{
    if(c=='d'&&d=='b')
        return 1;
    if(c=='b'&&d=='d')
        return 1;
    if(c=='p'&&d=='q')
        return 1;
    if(c=='q'&&d=='p')
        return 1;
    return 0;
}
int lk()
{
    int l=0,r=strlen(ch)-1;
    while(l<=r)
    {
        if((ch[l]==ch[r]&&path(ch[l]))||lp(ch[l],ch[r]))
        {
            l++;r--;
        }
        else
            return 0;
    }
    return 1;
}
int main()
{
    scanf("%s",ch);
    if(lk())
        puts("TAK");
    else
        puts("NIE");
    return 0;
}
View Code
 
额  题意很重要
 
就是这个图的点能否被切分成两个集合,同一个集合中的点,不能有边相连。所以最后所有点都会被划分到两个集合内。
找出集合的大小m0,m1,边数就等于m0*m1, 题中有n-1边是原有的,答案即为m0*m1-(n-1)
dfs
码如下:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;

typedef long long ll;
const int N=1e5+7;
vector<int>edge[N];
int vis[N];
ll m0=0,m1=0;
void dfs(int n,int flag)
{
    if(flag)
        m0++;
    else
        m1++;
    vis[n]=1;
    for(int i=0;i<edge[n].size();i++)
        if(!vis[edge[n][i]])
            dfs(edge[n][i],!flag);
}
int main()
{
    int n,u,v;
    cin>>n;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n-1;i++)
    {
        cin>>u>>v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs(1,0);
    cout<<m0*m1-(n-1)<<endl;
    return 0;
}
View Code
 
题意:
已知a序列,以及c序列的大小的排名, c[i]=b[i]-a[i],且a[i],b[i]均是[l-r]范围内,求b序列,若不存在输出-1
 
操作顺序是从c序列的小到大,首先找到一个最小值 minn=(l-a[vis[0]]),然后下一个数为minn+1  ,b[i]=minn+1+a[i],若b[i]不在[l-r]范围内结束,输出-1 ,否则 b[i]=max(b[i],l) 继续操作
 
代码如下:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;

typedef long long ll;
const int N=1e5+7;
const int INF=1e9+7;
int a[N],b[N];
int vis[N];
int main()
{
    int n,l,r,p;
    scanf("%d%d%d",&n,&l,&r);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&p);
        vis[p-1]=i;
    }
    int minn=-INF,flag=0;
    for(int i=0;i<n;i++)
    {

        if(i==0)
        {
            b[vis[i]]=l;
            minn=l-a[vis[i]];
        }
        else
        {
            int x=minn+1+a[vis[i]];
            if(x>r)
            {
                flag=1;
                break;
            }
            else
                b[vis[i]]=max(l,x);
            minn=b[vis[i]]-a[vis[i]];
        }
    }
    if(flag)
        puts("-1");
    else
    {
        for(int i=0;i<n;i++)
            printf("%d%c",b[i],i==n-1?'\n':' ');
    }
    return 0;
}
View Code

 

 
题意:
给n个能源箱,问最后所有能量箱都为一样的最大值
能量转移会损失能量
 
二分  能源的范围[l-r]
 
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;
const int N=1e4+7;
int main()
{
    double l=1000,r=0;
    int n,k;
    double a[N];
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
    {
        scanf("%lf",&a[i]);
        l=min(l,a[i]);
        r=max(r,a[i]);
    }
    while(l+1e-9<=r)
    {
        double mid=(l+r)*1.0/2.0;
        double ans=0;
        for(int i=0;i<n;i++)
        {
            if(a[i]>mid)
            {
                ans+=mid;
                ans+=(a[i]-mid)*(100-k)*1.0/100.0;
            }
            else
                ans+=a[i];
        }
        if(ans>n*mid)
            l=mid;
        else
            r=mid;
    }
    printf("%.9lf\n",l);
    return 0;
}
View Code

 

 

F - Roads not only in Berland

题意:

已知n个城市,城市之间不能形成环,问要修改那条路,和建成那条路

并查集 , 若u和v 的祖先已经相同,则这条路应该废除的,最后把是根节点建立在一起

代码如下:

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define PINT pair<int,int>
using namespace std;

const int N=1e3+7;
int pre[N];
int find(int x)
{
    int r=x;
    while(pre[r]!=r)
          r=pre[r];
    int i=x,j;
    while(i!=r)
    {
         j=pre[i];
         pre[i]=r;
         i=j;
    }
    return r;
}
void add(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
        pre[fy]=fx;
}
int main()
{
    vector<PINT>q;
    vector<int>p;
    q.clear();
    for(int i=0;i<N;i++)
        pre[i]=i;
    int n,u,v;
    scanf("%d",&n);
    for(int i=0;i<n-1;i++)
    {
        scanf("%d%d",&u,&v);
        if(find(u)==find(v))
            q.push_back(make_pair(u,v));
        else
            add(u,v);
    }
    printf("%d\n",q.size());
    for(int i=1;i<=n;i++)
        if(pre[i]==i)
            p.push_back(i);
    for(int i=0;i<q.size();i++)
        printf("%d %d %d %d\n",q[i].first,q[i].second,p[i],p[i+1]);
    return 0;
}
View Code

 

 

 

转载于:https://www.cnblogs.com/lemon-jade/p/8321804.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值