BestCoder 1st Anniversary

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)(1≤T≤10?5??), 表示测试数据组数. 然后对于每组数据:

一行包含4个整数 n, m, p, q (1 \le n, m, p, q \le 10^4)(1≤n,m,p,q≤10?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;
}

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 n1≤l?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)(1≤T≤100), 表示测试数据组数. 然后对于每组数据:

一行包含一个仅含小写字母的字符串ss (1 \le |s| \le 100)(1≤∣s∣≤100).

输出描述

对于每组数据, 如果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;
}

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)(n≥1)项是3n(n-1)+13n(n−1)+1. 现在他想知道对于一个给定的整数mm, 是否可以表示成若干项上述数列的和. 如果可以, 那么需要的最小项数是多少?

例如, 22可以表示为7+7+7+17+7+7+1, 也可以表示为19+1+1+119+1+1+1.

输入描述

输入有多组数据. 第一行有一个整数TT (1 \le T \le 10^4)(1≤T≤10?4??), 表示测试数据组数. 然后对于每组数据:

一行包含1个整数 mm (1 \le m \le 10^9)(1≤m≤10?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(m−k)mod6=0即可.

证明如下: 3n(n-1)+1 = 6(n*(n-1)/2)+13n(n−1)+1=6(n∗(n−1)/2)+1, 注意到n*(n-1)/2n∗(n−1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示. 枚举需要kk个, 那么显然m=6(km=6(k个三角形数的和)+k)+k, 由于k \ge 3k≥3, 只要m-km−k是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;
}

				
时间: 2024-10-10 01:10:17

BestCoder 1st Anniversary的相关文章

BestCoder 1st Anniversary($) 1003 Sequence

题目传送门 1 /* 2 官方题解: 3 这个题看上去是一个贪心, 但是这个贪心显然是错的. 4 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k(k>2), 使得(m-k)mod6=0即可. 5 证明如下: 6 3n(n-1)+1=6(n*(n-1)/2)+1, 注意到n*(n-1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示. 7 枚举需要k个, 那么显然m=6(k个三角形数的和)+k, 由于k≥3, 只要m?k是6的倍数就一定是有解的

hdu 5311 Hidden String (BestCoder 1st Anniversary ($))(深搜)

http://acm.hdu.edu.cn/showproblem.php?pid=5311 Hidden String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1499    Accepted Submission(s): 534 Problem Description Today is the 1st anniversar

BestCoder 1st Anniversary ($) 1001 Souvenir

Souvenir Accepts: 901 Submissions: 2743 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Problem Description Today is the 1st anniversary of BestCoder. Soda, the contest manager, wants to buy a souvenir for each cont

BestCoder 1st Anniversary ($) 题解

Souvenir 问题描述 今天是BestCoder一周年纪念日. 比赛管理员Soda想要给每个参赛者准备一个纪念品. 商店里纪念品的单价是p元, 同时也可以花q元购买纪念品套装, 一个套装里有m个纪念品. 今天总共有n个参赛者, Soda想要知道最少需要花多少钱才可以给每个人都准备一个纪念品. 输入描述 输入有多组数据. 第一行有一个整数T (1≤T≤105), 表示测试数据组数. 然后对于每组数据: 一行包含4个整数 n,m,p,q (1≤n,m,p,q≤104). 输出描述 对于每组数据输

BestCoder 1st Anniversary ($) 1002.Hidden String

Hidden String Accepts: 437 Submissions: 2174 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) 问题描写叙述 今天是BestCoder一周年纪念日. 比赛管理员Soda有一个长度为的字符串. 他想要知道是否能找到的三个互不相交的子串, , 满足下列条件: 1. 2. , , 依次连接之后得到字符串"anniversary". 输

BestCoder 1st Anniversary ($) Hidden String(深搜)

题意:给一个字符串s,问s中先后出现的三个子串是否能组成"anniversary" 解析:深搜,搜的层次小于等于三而且找到完整字符"anniversary"即正确,否则错误   #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn = 1e6; char s[1

BestCoder 1st Anniversary 1002-1005

1002 Hidden String 这个题怎么暴力怎么搞就好了. 可以枚举最长匹配前缀, 和最长匹配后缀, 中间暴力for. 1 /*Author :usedrose */ 2 /*Created Time :2015/7/25 19:05:28*/ 3 /*File Name :2.cpp*/ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <sstream

【BestCoder 1st Anniversary】

AB题都是签到题.... C 题意: 有一串数列,An=3*n*(n-1)+1 然后要从A数列中选取尽量少个数(可重复),使得Sum(An)=m 题解: 贪心地想,能拿大就拿大很明显就是错的...[哪里明显了...[反正就是错的 然后3*n*(n-1)+1=6*n*(n-1)/2+1,而n*(n-1)/2是三角形数,任意一个自然数最多只需要3个三角形数即可表示 所以设m是由k个数组成的,m=Sum(3*n*(n-1)+1)=6*(k个三角形数之和)+k 所以我们分情况来看:假如k=1和2则直接求

HDU 5312 Sequence(三角形数应用)——BestCoder 1st Anniversary ($)

传送门 Sequence Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1424    Accepted Submission(s): 442 Problem Description Today, Soda has learned a sequence whose n-th (n≥1) item is 3n(n?1)+1. Now