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

BestCoder 1st Anniversary ($) 题解

时间:2015-07-26 21:01:12      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:bestcoder   比赛   

Souvenir

问题描述
今天是BestCoder一周年纪念日. 比赛管理员Soda想要给每个参赛者准备一个纪念品. 商店里纪念品的单价是p元, 同时也可以花q元购买纪念品套装, 一个套装里有m个纪念品.

今天总共有n个参赛者, Soda想要知道最少需要花多少钱才可以给每个人都准备一个纪念品.
输入描述
输入有多组数据. 第一行有一个整数T (1T105), 表示测试数据组数. 然后对于每组数据:

一行包含4个整数 n,m,p,q (1n,m,p,q104).
输出描述
对于每组数据输出最小花费.
输入样例
2
1 2 2 1
1 2 3 4
输出样例
1
3
Hint
对于第一组数据, Soda可以1元购买一个套装. 对于第二组数据, Soda可以直接花3元购买一个纪念品.

代码:

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif

#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

#define rep(i,j,k) for(int i=(int)j;i<(int)k;++i)
#define per(i,j,k) for(int i=(int)j;i>(int)k;--i)
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))

typedef long long LL;
typedef unsigned long long LLU;
typedef double db;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int t,ans,res,cnt,tmp;

inline LL read()
{
    int c=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        c=c*10+ch-'0';
        ch=getchar();
    }
    return c*f;
}
int n,m,p,q;
int main()
{
    t=read();
    while(t--)
    {
        n=read();
        m=read();
        p=read();
        q=read();
        int h1=p*n;///全部买单价
        int h2,h3;
        if(n%m==0){///倍数关系
            h2 = n/m*q;///全部套装
        }
        else{  
            h2 = (n/m+1)*q;///人数不够的,加一
        }
        h3 = n/m*q + n%m*p;///n%m的零头买单价
        printf("%d\n",min(h1,min(h2,h3)));
    }
    return 0;
}


B Hidden String

问题描述
今天是BestCoder一周年纪念日. 比赛管理员Soda有一个长度为n的字符串s. 他想要知道能否找到s的三个互不相交的子串s[l1..r1], s[l2..r2], s[l3..r3]满足下列条件:

  1. 1l1r1<l2r2<l3r3n

  2. s[l1..r1], s[l2..r2], s[l3..r3]依次连接之后得到字符串"anniversary".
输入描述
输入有多组数据. 第一行有一个整数T (1T100), 表示测试数据组数. 然后对于每组数据:

一行包含一个仅含小写字母的字符串s (1|s|100).
输出描述
对于每组数据, 如果Soda可以找到这样三个子串, 输出"YES", 否则输出"NO".
输入样例
2
annivddfdersewwefary
nniversarya
输出样例
YES
NO


代码:

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif

#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

#define rep(i,j,k) for(int i=(int)j;i<(int)k;++i)
#define per(i,j,k) for(int i=(int)j;i>(int)k;--i)
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))

typedef long long LL;
typedef unsigned long long LLU;
typedef double db;
const int N=1e5+10;
const int inf=0x3f3f3f3f;

char str[N];
bool vis[N];
int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}};

inline LL read()
{
    int c=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        c=c*10+ch-'0';
        ch=getchar();
    }
    return c*f;
}
int t,n,m,p,q,len;
int ok;
char s1[N];
char pp[12]="anniversary";
void dfs(int u,int k,int num)
{
    if(k==11&&num==3){
        ok=1;
        return ;
    }
    for(int i=u; i<len; ++i){
        int h1=k;
        while(s1[i]==pp[h1])
        {
            dfs(i+1,h1+1,num+1);
            i++;
            h1++;
        }
    }
}
int main()
{
    t=read();
    while(t--){
        scanf("%s",&s1);
        len=strlen(s1);
        ok=0;
        dfs(0,0,0);
        if(ok) puts("YES");
        else puts("NO");
    }
    return 0;
}
C Sequence

问题描述
Soda习得了一个数列, 数列的第n (n1)项是3n(n?1)+1. 现在他想知道对于一个给定的整数m, 是否可以表示成若干项上述数列的和. 如果可以, 那么需要的最小项数是多少?

例如, 22可以表示为7+7+7+1, 也可以表示为19+1+1+1.
输入描述
输入有多组数据. 第一行有一个整数T (1T104), 表示测试数据组数. 然后对于每组数据:

一行包含1个整数 m (1m109).
输出描述
对于每组数据输出最小花费.
输入样例
10
1
2
3
4
5
6
7
8
22
10
输出样例
1
2
3
4
5
6
1
2
4
4
【解题思路】:AC率 1.7%,暂时没有想到好的解法~~

D Bipartite Graph

问题描述
Soda有一个n个点m条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的.
输入描述
输入有多组数据. 第一行有一个整数T (1T100), 表示测试数据组数. 然后对于每组数据:

第一行报包含两个整数nm, (2n10000,0m100000).

接下来m行, 每行两个整数uv(1u,vn,vu), 表示uv之间有一条无向边.

输入保证给出的图是二分图, 没有重边, 没有自环. 大部分数据都是小数据.
输出描述
对于每组数据, 输出Soda最多能加的边数.
输入样例
2
4 2
1 2
2 3
4 4
1 2
1 4
2 3
3 4
输出样例
2
0
【思路】:
首先二分图可以分成两类点XY, 完全二分图的边数就是|X|?|Y|.我们的目的是max{|X|?|Y|}, 并且|X|+|Y|=n.

把原图黑白染色, 每个联通块有ai个黑点, bi个白点, 于是就是要确定ai属于X还是属于Y. 然后我们考虑dp, dpi,x表示用了前i个联通块, |X|=x是否可行. dp方程很容易确定, dpi,x=dpi?1,x?a[i] or dpi?1,x?b[i].

直接暴力是O(n2)的, 可以考虑用bitset优化, 这样就可以过了. 实际上由于数据很难造, 一些稍加优化的n2也可以过的
代码:

#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif

#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

#define rep(i,j,k) for(int i=(int)j;i<(int)k;++i)
#define per(i,j,k) for(int i=(int)j;i>(int)k;--i)
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))

typedef long long LL;
typedef unsigned long long LLU;
typedef double db;
const int N=1e5+10;
const int inf=0x3f3f3f3f;

char str[N];
bool vis[N];

int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}};

inline LL read()
{
    int c=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    return c*f;
}
__int64  t,n,m,p,q,u,v;
int len;
char s1[N];
char s2[N];
int ok;

struct graph
{
    int mat[2];
} g[N];

vector<int>V[N];
int vec;

void dfs(int u,int k)
{
    vis[u]=true;
    g[vec].mat[k]++;
    for(int i=0; i<V[u].size(); i++){
        int v=V[u][i];
        if (!vis[v])
            dfs(v,k^1);
    }
}

bool cmp(const graph &x,const graph &y)
{
    return x.mat[0]-x.mat[1] > y.mat[0]-y.mat[1];
}

int main()
{
    t=read();
    while(t--){
        scanf("%I64d%I64d",&n,&m);
        for(int i=1; i<=n; i++){
            V[i].clear();
            vis[i]=0;
        }
        for(int i=1; i<=m; i++){
            u=read();
            v=read();
            V[u].push_back(v);
            V[v].push_back(u);
        }
        vec=0;
        for(int i=1; i<=n; i++){
            if (!vis[i]){
                g[vec].mat[0]=g[vec].mat[1]=0;
                dfs(i,0);
                vec++;
            }
        }
        for(int i=0; i<vec; i++){
            if (g[i].mat[0]<g[i].mat[1])
                swap(g[i].mat[0],g[i].mat[1]);
        }
        sort(g,g+vec,cmp);
        __int64 x=0,y=0;
        for (int i=0; i<vec; i++){
            if(x>y) swap(x,y);
            x+=g[i].mat[0];
            y+=g[i].mat[1];
        }
        printf("%I64d\n",x*y-m);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

BestCoder 1st Anniversary ($) 题解

标签:bestcoder   比赛   

原文地址:http://blog.csdn.net/u013050857/article/details/47065363

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