Codeforces Round #403 (Div. 2)(A-E 未完)

A. Andryusha and Socks

题意:现在有n对数字,每次拿出一个数字到桌子上,如果这个数字以前就出现过,就把当前数字和以前数字都都拿走,问桌子上最多有多少种袜子
思路:简单模拟

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
int a[100010];
int main(){
    int ans=0;
    int maxn=-1;
    scanf("%d",&n);
    for(int i=0;i<2*n;i++)
    {
        int temp;
        scanf("%d",&temp);
        if(a[temp]==0)
        {
            a[temp]++;
            ans++;
            maxn=max(maxn,ans);
        }
        else
        {
            ans--;
        }
    }
    printf("%d\n",maxn);
}

B. The Meeting Place Cannot Be Changed

题意:现在n个人站在一条路上,每个人都有一个坐标和一个速度,现在要让所有人跑到一个点上,问所需最小时间是多少
思路:二分,二分时间,看该时间能不能让所有人跑到某个点,浮点数二分用for循环100次即可提炼精度,不得不说浮点数二分比整数二分好写多了= =

代码:

#include<bits/stdc++.h>
using namespace std;
struct poi{
    int x;
    int s;
}a[60100];
bool cmp(poi w,poi e)
{
    return w.x<e.x;
}
int n;
bool judge(double time)
{
    double len=1.0*a[0].x+1.0*time*a[0].s;
    for(int i=1;i<n;i++)
    {
        if(a[i].x<len)
        {
            len=min(len,1.0*a[i].x+1.0*time*a[i].s);
        }
        else
        {
            if(1.0*a[i].x-1.0*time*a[i].s>len)
                return false;
        }
    }
    return true;

}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i].x);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i].s);
    sort(a,a+n,cmp);
    double l=0;double r=1000000000;
    for(int i=0;i<100;i++)
    {
        double mid=(l+r)/2;
        if(judge(mid))
            r=mid;
        else
            l=mid;
    }
    printf("%.7f\n",(l+r)/2.0);
}

C. Andryusha and Colored Balloons

题意:给你一个图,任意点和它所连的点,这些点之间的任意两点的颜色不能相同,问最少要几种颜色,并给出配色方案
思路:DFS,DFS的时候一边更新最少颜色数,一边染色,在DFS的时候,记录该点的颜色和其之前一个点的颜色会好写一些

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> q[200010];
int b[200010];
int ans=0;
void dfs(int now,int fa,int bef,int me)
{
    int col=1;
    ans=max(ans,(int)q[now].size()+1);
    for(int i=0;i<q[now].size();i++)
    {

        if(q[now][i]!=fa)
        {
            while(col==bef||col==me)
            col++;
                b[q[now][i]]=col;
            col++;

            dfs(q[now][i],now,me,col-1);
        }
    }
    return ;
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n-1;i++)
    {
        int tempa,tempb;
        scanf("%d%d",&tempa,&tempb);
        q[tempa].push_back(tempb);
        q[tempb].push_back(tempa);
    }
    b[1]=1;
    dfs(1,-1,-1,1);
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)
    {
        if(i!=1) printf(" ");
        printf("%d",b[i]);
    }
    puts("");
}

D. Innokenty and a Football League

题意:现在有N个队伍,每个队伍的全名有两个部分,现在有给每个队伍起简称,第一种简称是第一个名字的前三位,第二种是第第一个名字的前两位加第二个名字的第一位。每个队伍都想优先使用第一种,但是如果若干个队伍的第一种相同了,那么他们只能使用第二种,如果一个队伍的第一种被占用了,那它也只能使用第二种了
思路:map容器,如果有的队伍第一种名称相同,那么他们都别无选择的使用第二种,如果有个队伍的第一个名字被用了,那他只能用第二种,如果第二个被用了,那他只能用第一种,如果都没有被使用,那就使用第一种。这个题的坑就在,即使两个队伍的第一个名字没有出现重复,也是可能相互制约的,要考虑好优先级才能AC

代码:

#include<bits/stdc++.h>
using namespace std;
map<int,int> mp;//只是用来查看当前字符串以前有没有检查过
map<int,int> mpp;//判断某个名字是否冲突
char a[1010][2][25];//储存原数组串
char ans[1010][3];//储存答案
bool did[1010];//判断是否已经有答案了
int name(int a,int b,int c){return a*10000+b*100+c;}//hash名字
int main(){
    int n;
    scanf("%d",&n);
    bool judge=true;
    for(int i=0;i<n;i++) scanf("%s%s",a[i][0],a[i][1]);
    for(int i=0;i<n;i++)//用来看当第一种名字相同时,第二种名字是否出现冲突
    {
        int temp=name(a[i][0][0]-'a',a[i][0][1]-'a',a[i][0][2]-'a');
        if(mp[temp]>=1)
            continue;
        else
        {
            mp[temp]=1;
            for(int j=i+1;j<n;j++)
            {
                int tempa=name(a[j][0][0]-'a',a[j][0][1]-'a',a[j][0][2]-'a');
                if(tempa==temp)
                {
                    mp[temp]=2;
                    for(int k=i;k<n;k++)
                    {
                        int tempb=name(a[k][0][0]-'a',a[k][0][1]-'a',a[k][1][0]-'a');
                        int tempc=name(a[k][0][0]-'a',a[k][0][1]-'a',a[k][0][2]-'a');
                        if(tempc==temp){
                            mpp[tempb]++;
                            did[k]=true;
                            ans[k][0]=a[k][0][0]; ans[k][1]=a[k][0][1]; ans[k][2]=a[k][1][0];
                            if(mpp[tempb]==2){
                                judge=false;
                                break;
                            }
                        }
                    }
                    break;
                }
            }
        }
    }

    if(judge)
    {
        bool change=false;
        for(int i=0;;i++)//当某个队伍别无选择时,就能确定他的队名,不断循环到没有更新为止
        {
            if(i==n)
            {
                i=0;
                if(change==0) break;
                change=false;
            }
            int temp=name(a[i][0][0]-'a',a[i][0][1]-'a',a[i][0][2]-'a');
            if(mp[temp]==1&&did[i]==0)//第一种队名没重复且名字不确定
            {
                if(mpp[temp]==1)//第一个名字被用了
                {
                    temp=name(a[i][0][0]-'a',a[i][0][1]-'a',a[i][1][0]-'a');
                    if(mpp[temp]==1)//第二个也被用了就没办法了
                    {
                        judge=false;
                        break;
                    }
                    else{
                        change=true;
                        ans[i][0]=a[i][0][0]; ans[i][1]=a[i][0][1];ans[i][2]=a[i][1][0];
                        did[i]=true;
                        mpp[temp]++;
                    }
                }
                else
                {
                    temp=name(a[i][0][0]-'a',a[i][0][1]-'a',a[i][1][0]-'a');
                    if(mpp[temp]==1)//第二个被用了就只能用第一个了
                    {
                        change=true;
                        temp=name(a[i][0][0]-'a',a[i][0][1]-'a',a[i][0][2]-'a');
                        ans[i][0]=a[i][0][0]; ans[i][1]=a[i][0][1]; ans[i][2]=a[i][0][2];
                        did[i]=true;
                        mpp[temp]++;
                    }
                }
            }
        }
        if(judge)
        {
            printf("YES\n");
            for(int i=0;i<n;i++)
                if(did[i])
                    printf("%c%c%c\n",ans[i][0],ans[i][1],ans[i][2]);
                else
                    printf("%c%c%c\n",a[i][0][0],a[i][0][1],a[i][0][2]);
        }
        else
            printf("NO\n");
    }
    else
        printf("NO\n");
}

E. Underground Lab

题意:有n个点,m个边,现在有k个起点,每个点最多走 (2n)/k 个点,保证有解,求每个点的行动轨迹
思路:DFS,这个题的关键就是要看懂那个向上取整。。。发现是个向上取整的话,就会发现,每个点就算跑两次都能把这个图跑完,那么只要DFS一次,记录下路径,然后分k次输出就好了。。。只能说这个题如果能看懂那个向上取整就毫无难度了,然而我看了题解才看懂。。。。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
vector<int> a[maxn];
bool did[maxn];
int ans[maxn*2];
int cnt=0;
void dfs(int now)
{
    did[now]=true;
    ans[cnt++]=now;
    for(int i=0;i<a[now].size();i++)
    {
        if(!did[a[now][i]]){
            dfs(a[now][i]);
            ans[cnt++]=now;
        }
    }
}
int main(){
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0,v,u;i<m;i++)
    {
        scanf("%d%d",&v,&u);
        a[v].push_back(u);
        a[u].push_back(v);
    }
    int step=(2*n+k-1)/k;
    dfs(1);cnt--;
    for(int i=0;i<k;i++)
    {
        int l=min(step,cnt+1);
        if(l==0)
        {
            printf("1 1\n");
            continue;
        }
        printf("%d",l);
        for(int j=0;j<l&&cnt>=0;j++,cnt--)
            printf(" %d",ans[cnt]);
        puts("");
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值