套题 codeforces 360

A题:Opponents

直接模拟

#include <bits/stdc++.h>
using namespace std;
char ch[200];
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        int p=0,sta=1,first=1,ans;
        for(int i=0;i<k;i++)
        {
            sta=1;
            scanf("%s",ch);
            for(int i=0;i<n;i++) sta&=(ch[i]-‘0‘);
            if(sta==0) p++;
            if(sta==1||(i==k-1))
            {
                if(first) {ans=p;first=0;}
                else
                {
                    ans=max(ans,p);
                }
                p=0;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

B题: Lovely Palindromes
偶数长度的回文串
可以把这个回文串当做两半来处理,对于任何一个数字,只要把它反转后加到
数字尾,就可以形成一个回文串,且符合偶数长度的条件
既然任何数字都可以,那么第n个数就是以n来构造的

#include <bits/stdc++.h>
using namespace std;
const int Max=1e5+10;
char ch[Max];
int main()
{
    while(~scanf("%s",ch))
    {
        printf("%s",ch);
        reverse(ch,ch+strlen(ch));
        printf("%s\n",ch);
    }
    return 0;
}

C题:NP-Hard Problem
要求将一张图分成两个顶点集合,每个集合包含所有的边
要使得这样的集合成立,必须把每一条边上的两点分别分到两个集合中去
可以利用并查集分点,一个集合祖先节点小于等于n(小于等于(因为n+n))
另一个祖先节点大于n。
这两个集合有没有交集取决于同一条边上的两个顶点不能在同一集合

#include <bits/stdc++.h>
using namespace std;
const int Max=1e5+10;
int fa[Max*2];
int find(int x)
{
    return fa[x]==-1?x:fa[x]=find(fa[x]);
}
void Union(int x,int y)
{
    int f1=find(x),f2=find(y);
    if(f1!=f2) fa[f1]=f2;
}
vector<int>ans1,ans2;
int vis[Max];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        memset(fa,-1,sizeof(fa));
        memset(vis,0,sizeof(vis));
        int u,v,flag=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            if(find(u)==find(v)) flag=1;  //两个顶点已经在同一集合,无解
            Union(u,v+n);
            Union(u+n,v);
            vis[u]=vis[v]=1;
        }
        ans1.clear();ans2.clear();
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]) continue;
            if(find(i)<=n) ans1.push_back(i);
            else ans2.push_back(i);
        }
        if(ans1.empty()||ans2.empty()||flag) puts("-1");
        else
        {
            if(ans1.size()>ans2.size()) swap(ans1,ans2);
            printf("%d\n",ans1.size());
            for(int i=0;i<ans1.size();i++)
            {
                if(i) printf(" ");
                printf("%d",ans1[i]);
            }
            printf("\n%d\n",ans2.size());
            for(int i=0;i<ans2.size();i++)
            {
                if(i) printf(" ");
                printf("%d",ans2[i]);
            }
            puts("");
        }
    }
    return 0;
}

同样地,既然已经知道了解这道题的关键就是让每一条边的两个点分散到
两个不同的集合里面,那么直接dfs进行染色也是一个简洁易写的方法

#include <bits/stdc++.h>
using namespace std;
const int Max=1e5+10;
vector<int>G[Max];
vector<int>ans1,ans2;
int vis[Max],col[Max];
bool dfs(int u,int c,int pre)
{
    col[u]=c;
    int v;
    for(int i=0;i<G[u].size();i++)
    {
        v=G[u][i];
        if(v==pre) continue;
        if(col[v]==c)  return 0;
        if(col[v]!=-1) continue;
        if(!dfs(v,!c,u)) return 0;
    }
    return 1;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        memset(vis,0,sizeof(vis));
        memset(col,-1,sizeof(col));
        int u,v;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
            vis[u]=vis[v]=1;
        }
        int root,flag=0;
        for(int i=1;i<=n;i++) if(vis[i])
        {
            root=i;
            if(col[root]!=-1) continue;
            if(!dfs(root,1,0)) flag=1;
        }
        if(flag) puts("-1");
        else
        {
            ans1.clear();ans2.clear();
            for(int i=1;i<=n;i++)
            {
                if(col[i]==1) ans1.push_back(i);
                if(col[i]==0) ans2.push_back(i);
            }
            if(ans1.size()>ans2.size()) swap(ans1,ans2);
            printf("%d\n",ans1.size());
            for(int i=0;i<ans1.size();i++)
            {
                if(i) printf(" ");
                printf("%d",ans1[i]);
            }
            printf("\n%d\n",ans2.size());
            for(int i=0;i<ans2.size();i++)
            {
                if(i) printf(" ");
                printf("%d",ans2[i]);
            }
            puts("");
        }
    }
    return 0;
}

D题:Remainders Game
已知:
x mod c1 = m1
x mod c2 = m2
......
x mod cn = mn
这里要求知道x mod (k)的值,那么就要求lcm(c1,c2,c3,.....,cn)==k,并且ci之间互质

#include <bits/stdc++.h>
#define scan(x,y) scanf("%d%d",&x,&y)
using namespace std;
typedef long long LL;
const int Max=1e5+10;
int n,m;
LL gcd(LL a,LL b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    scan(n,m);
    LL ans=1;
    int x;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        ans=gcd((LL)m,ans*(LL)x/gcd(ans,x));
    }
    if(ans==(LL)m) cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
    return 0;
}

E题:The Values You Can Make
有n个价值不一的硬币,问能够凑出的所有面值(<=m)
dp[i][j],意为已经拥有j面值的情况下,能否凑成j面值
1.dp[0][0]=1
2.if(dp[l-x][j]) dp[l][j]=1 and dp[l][j+x]=1;
3.已拥有的硬币转移方向应该从大到小,因为用一枚硬币不能使用多次,不能对后面的
数值持续影响

#include <bits/stdc++.h>
using namespace std;
const int Max=500+10;
short dp[Max][Max];
vector<int>ans;
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        int x;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            for(int l=k;l>=x;l--)
            {
                for(int r=0;r<=k-x;r++)
                {
                    if(dp[l-x][r]) dp[l][r]=dp[l][r+x]=1;
                }
            }
        }
        ans.clear();
        for(int i=0;i<=k;i++)
        {
            if(dp[k][i]) ans.push_back(i);
        }
        printf("%d\n",ans.size());
        for(int i=0;i<ans.size();i++)
        {
            if(i) printf(" ");
            printf("%d",ans[i]);
        }
        puts("");
    }
    return 0;
}

时间: 2024-10-05 16:26:44

套题 codeforces 360的相关文章

Educational Codeforces Round 15 套题

这套题最后一题不会,然后先放一下,最后一题应该是大数据结构题 A:求连续最长严格递增的的串,O(n)简单dp #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <vector> usi

2017年8月14日套题记录 | 普及组

写在前面 今天登洛谷发现离Noip剩下88天了??(虽然看起有点久),然后觉得似乎水了一个暑假什么也没做(虽然学了点数据结构和一些奇奇Gaygay的东西),于是打开题库发现去年Long Happy的集训套题我似乎没有提交过,那就一天一套题,顺便码个题解+心得(雾? T2.传作业 题目描述 某十三同学一日上学迟到,此时已经开始上早自习了,所以他只好请同学帮忙把作业传到组长那里.由于刚开学不久,某十三同学还没来得及认识所有同学,所以传作业时只好找熟悉的同学.已知某十三与组长之间有N个他熟悉的同学,并

应试教育:你是在“套题”还是在“解决问题”?

?为什么当初会采用"背题型"的方式? ?"背题型"的局限性在哪? ?建构"知识体系"优势在哪? ?"题海战术"的认知错误 ?学习和考试的本质 声明:此文纯属个人学习方法总结. 1.为什么当初会采用"背题型"的方式? 以前上了高中,由于身边学霸太多,为了急于缩短与他们之间的天壤之别,总想着调整自己的学习方法. 本来自己就没什么学习方法,加上老师布置下做不完的题目,况且时常听到"题海战术"的

套题T6

过节(festival.cpp/c/pas) Dxy帮老师们过教师节的时候需要购买礼物.货架上有n 种礼物,每种礼物有不同的个数.每种礼物有价值和花费两种属性,帮他算出最大可以得到的价值.M是带的钱数有多少 Input: 第一行两个数n,m 第2到n+1行:每行三个数a,b,c,表示一种礼物的个数,花费和价值.   Output: 最大可得价值.   样例输入: 1  1 1  1  1   样例输出: 1 a*b(mod.cpp/c/pas) 没错dxy的题目就是这么简单. 输入: 第一行一个

套题T4

Problem 1 无聊的gcd(gcd.c/cpp/pas) 话说出题人不会被查水表吧. 简单的问题描述:从N个正整数里面取出K个数的最大公因数最大是多少.(请将答案乘上k之后输出哦,谢谢合作.) 输入格式 第一行两个正整数N,K. 第二行n个正整数 输出格式 输出一个正整数表示最大的最大公因数. 样例输入 3 1 1 2 3 样例输出 3 数据说明 对于30%的数据,保证k≤n≤20. 对于50%的数据,保证输入中所有数小于5000. 对于100%的数据,保证输入中所有数小于500000,k

[暑假集训]区域赛套题集

2014-07-03 [浙江第11届省赛]ZOJ 3785 What day is that day?  (打表找循环节) [暑假集训]区域赛套题集

套题T5//各种树

树(tree) [题目描述] 方方方种下了三棵树,一年后,第一棵树长出了n个节点. 方方方会向你提出m个询问,每个询问给出两个数i,j,你需要回答i号节点和j号节点在树上的距离. [输入数据] 第一行两个整数n,m.接下来n-1行每行两个整数a,b表示一条边.接下来m行每行两个整数i,j表示询问. [输出数据] m行,每行一个整数表示答案. [样例输入] 3 2 1 2 1 3 3 2 1 1 [样例输出] 2 0 [数据范围] 对于30%的数据,n,m<=1000. 对于100%的数据,n,m

水题 Codeforces Round #286 (Div. 2) A Mr. Kitayuta&#39;s Gift

题目传送门 1 /* 2 水题:vector容器实现插入操作,暴力进行判断是否为回文串 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 #include <string> 9 #include <vector> 10 using namespace std; 11 12 const int MAXN

Moscow Pre-Finals Workshop 2016. Japanese School OI Team Selection. 套题详细解题报告

写在前面 谨以此篇题解致敬出题人! 真的期盼国内也能多出现一些这样质量的比赛啊.9道题中,没有一道凑数的题目,更没有码农题,任何一题拿出来都是为数不多的好题.可以说是这一年打过的题目质量最棒的五场比赛之一了!(其中G.I和D题简直是好题中的好题!) 由于网上没有任何这套题的题解,我每道题都绞尽脑汁想了好久(尤其是D题.I题和H题证明),在此认认真真的写一篇博客,也真心希望好题能被更多的人发现和赞美. 题目概述 题目 思维难度  推荐指数 考点 A 3  ☆☆☆☆ 最长上升子序列 B 暂留坑,>7