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

BestCoder 1st Anniversary

时间:2015-09-06 23:01:24      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:

problem 1001

Souvenir

 
 Accepts: 901
 
 Submissions: 2743
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 262144/262144 K (Java/Others)
问题描述
今天是BestCoder一周年纪念日. 比赛管理员Soda想要给每个参赛者准备一个纪念品. 商店里纪念品的单价是p元, 同时也可以花q元购买纪念品套装, 一个套装里有mm个纪念品.

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

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

思路:当m小于n,你可以就p*m与q谁大谁小进行选择,当m大于n,就p*n与q谁大谁小进行考虑

技术分享
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    int T;
    cin>>T;
    int n,m,p,q;
    while(T--)
    {
     cin>>n>>m>>p>>q;
     int sum=0;
     while(n>=m)
     {
         if(p*m>q)
            sum+=q;
         else
            sum+=p*m;
         n-=m;
     }
     if(p*n<q)
            sum+=p*n;
     else
            sum+=q;
     cout<<sum<<endl;
    }
    return 0;
}
View Code

problem1002

Hidden String

 
 Accepts: 437
 
 Submissions: 2174
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 262144/262144 K (Java/Others)
问题描述
今天是BestCoder一周年纪念日. 比赛管理员Soda有一个长度为nn的字符串ss. 他想要知道能否找到ss的三个互不相交的子串s[l_1..r_1]s[l?1??..r?1??], s[l_2..r_2]s[l?2??..r?2??], s[l_3..r_3]s[l?3??..r?3??]满足下列条件:

  1. 1 \le l_1 \le r_1 < l_2 \le r_2 < l_3 \le r_3 \le n1l?1??r?1??<l?2??r?2??<l?3??r?3??n

  2. s[l_1..r_1]s[l?1??..r?1??], s[l_2..r_2]s[l?2??..r?2??], s[l_3..r_3]s[l?3??..r?3??]依次连接之后得到字符串"anniversary".
输入描述
输入有多组数据. 第一行有一个整数TT (1 \le T \le 100)(1T100), 表示测试数据组数. 然后对于每组数据:

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

可以使用搜索求,字符串长度也不算长。。。。。。。

技术分享
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char goal[]="anniversary";
char a[110];
int len,glen;

void Init()
{
    cin>>a;
    len=strlen(a);
}

bool DFS(int ti,int gi,int num)
{
    if(ti<=len&&gi>=glen&&num<=3) return true;
    if(num>3) return false;
    for(int i=ti;i<len;i++)
    {
        int si=i,sg=gi;
        while(si<len&&sg<glen&&a[si]==goal[sg]) sg++,si++;
        if(si!=i&&DFS(si,sg,num+1)) return true;
    }
    return false;
}

void Work()
{
    if(DFS(0,0,0))
    cout<<"YES"<<endl;
    else
    cout<<"NO"<<endl;
}

int main()
{
    int T;
    glen=strlen(goal);
    cin>>T;
    while(T--)
    {
     Init();
     Work();
    }
    return 0;
}
View Code

 

problem1003

Sequence

 
 Accepts: 25
 
 Submissions: 1442
 Time Limit: 2000/2000 MS (Java/Others)
 
 Memory Limit: 262144/262144 K (Java/Others)
问题描述
Soda习得了一个数列, 数列的第nn (n \ge 1)(n1)项是3n(n-1)+13n(n1)+1. 现在他想知道对于一个给定的整数mm, 是否可以表示成若干项上述数列的和. 如果可以, 那么需要的最小项数是多少?

例如, 22可以表示为7+7+7+17+7+7+1, 也可以表示为19+1+1+119+1+1+1.
输入描述
输入有多组数据. 第一行有一个整数TT (1 \le T \le 10^4)(1T10?4??), 表示测试数据组数. 然后对于每组数据:

一行包含1个整数 mm (1 \le m \le 10^9)(1m10?9??).
输出描述
对于每组数据输出最小花费.
输入样例
10
1
2
3
4
5
6
7
8
22
10
输出样例
1
2
3
4
5
6
1
2
4
4
官方题解:

这个题看上去是一个贪心, 但是这个贪心显然是错的. 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k (k > 2)k(k>2), 使得(m - k) mod 6 = 0(mk)mod6=0即可.

证明如下: 3n(n-1)+1 = 6(n*(n-1)/2)+13n(n1)+1=6(n(n1)/2)+1, 注意到n*(n-1)/2n(n1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示. 枚举需要kk个, 那么显然m=6(km=6(k个三角形数的和)+k)+k, 由于k \ge 3k3, 只要m-kmk是6的倍数就一定是有解的

技术分享
#include <iostream>
#include <cstdio>
using namespace std;
const int  maxn=1e5+10;
int n;
int a[maxn];

int caculate(int m)
{
    for(int i=1;i<=n;i++)
    {
       if(a[i]==m)  return 1;
    }
    int j=n;
    for(int i=1;i<=n&&a[i]<m;i++)
    {
        while(a[i]+a[j]>m) j--;
        if(a[i]+a[j]==m) return 2;
    }
    return 0;
}

int main()
{
    int T;
    for(int i=1;i<maxn;i++)
    {
        a[i]=3*i*(i-1)+1;
        if(a[i]>1e9)
        {
            n=i;
            break;
        }
    }
    cin>>T;
    while(T--)
    {
     int m,ans;
     cin>>m;
     for(int k=1;k<=m;k++)
     {
         if(k==1||k==2)
         {
             ans=caculate(m);
             if(ans!=0)
             break;
         }
         else
         {
         if((m-k)%6==0) {ans=k;break;}
         }
     }
     cout<<ans<<endl;
    }
    return 0;
}
View Code

 



BestCoder 1st Anniversary

标签:

原文地址:http://www.cnblogs.com/zsyacm666666/p/4787511.html

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