BestCoder Round #84题解报告

本文针对BestCoder Round #84的比赛提供详细的解题思路与代码实现,包括Problem1001 Aaronson中关于寻找特定方程的最优解,Problem1002 Bellovin中关于最长上升子序列的构造问题,以及Problem1004 Dertouzos中关于最大正真因数的计数问题。

此文章可以使用目录功能哟↑(点击上方[+])

好久没办的bestcoder,今天重新开始做,结果着实被自己蠢哭,各种低端错,把自己坑掉分了...

链接→BestCoder Round #84

 Problem 1001 Aaronson

Accept: 0    Submit: 0
Time Limit: 4000/2000 MS (Java/Others)    Memory Limit : 131072/131072 K (Java/Others)

 Problem Description

Recently, Peter saw the equation . He wants to find a solution  in such a manner that is minimum and every x​i is non-negative.
给出一个不定方程 , 找出一组解 , 使得 最小, 并且每个x​i(0≤i≤m)都是非负的.

 Input

There are multiple test cases. The first line of input contains an integer T(1≤T≤10^5), indicating the number of test cases. For each test case:

The first contains two integers n and m(0≤n,m≤10^9).
输入包含多组数据, 第一行包含一个整数T(1≤T≤10^​5)表示测试数据组数. 对于每组数据:
第一行包含两个整数n和m(0≤n,m≤10^​9).

 Output

For each test case, output the minimum value of .

对于每组数据, 输出的最小值.

 Sample Input

10
1 2
3 2
5 2
10 2
10 3
10 4
13 5
20 4
11 11
12 3

 Sample Output

1
2
2
3
2
2
3
2
3
2

 Problem Idea

解题思路:

【题意】
我想中文题就不必解释了吧,唯一要注意的一点就是xi是非负整数


【类型】
暴力

【分析】
首先,不管三七二十一,先把2的各个次幂先打表保存

然后从满足条件的最大的次幂开始逐一判断,能取则取

这题被hack掉着实出乎意料,就因为手残,表没打全

【时间复杂度&&优化】
O(mT)

题目链接→HDU 5747 Aaronson

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 31;
const int M = 1005;
const int inf = 1000000007;
const int mod = 1000000007;
int s[N];
int main()
{
    int t,n,m,i,j,k,ans;
    s[0]=1;
    for(i=1;i<N;i++)
        s[i]=s[i-1]+s[i-1];
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%d%d",&n,&m);
        for(j=min(m,N-1);j>=0;j--)
            if(n>=s[j])
            {
                k=n/s[j];
                ans+=k;
                n-=k*s[j];
            }
        printf("%d\n",ans);
    }
    return 0;
}

 Problem 1002 Bellovin

Accept: 0    Submit: 0
Time Limit: 6000/3000 MS (Java/Others)    Memory Limit : 131072/131072 K (Java/Others)

 Problem Description

Peter has a sequence a1,a2,...,an and he define a function on the sequence -- F(a1,a2,...,an)=(f1,f2,...,fn), where fi is the length of the longest increasing subsequence ending with ai.

Peter would like to find another sequence b1,b2,...,bn in such a manner that F(a1,a2,...,an) equals to F(b1,b2,...,bn). Among all the possible sequences consisting of only positive integers, Peter wants the lexicographically smallest one.

The sequence a1,a2,...,an is lexicographically smaller than sequence b1,b2,...,bn, if there is such number i from 1 to n, that ak=bk for 1≤k<i and ai<bi.

Peter有一个序列a1,a2,...,an. 定义F(a1,a2,...,an)=(f1,f2,...,fn), 其中f​i是以ai结尾的最长上升子序列的长度.

Peter想要找到另一个序列b1,b2,...,bn使得F(a1,a2,...,an)和F(b1,b2,...,bn)相同. 对于所有可行的正整数序列, Peter想要那个字典序最小的序列.

序列a1,a2,...,an比b1,b2,...,bn字典序小, 当且仅当存在一个正整数i (1≤i≤n)满足对于所有的k (1≤k<i)都有ak = bk并且ai < bi.

 Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first contains an integer n (1≤n≤100000) -- the length of the sequence. The second line contains n integers a1,a2,...,an (1≤ai≤10^9).

输入包含多组数据, 第一行包含一个整数T表示测试数据组数. 对于每组数据:

第一行包含一个整数n (1≤n≤100000)表示序列的长度. 第二行包含n个整数a1,a2,...,an (1≤ai≤10^9).

 Output

For each test case, output n integers b1,b2,...,bn (1≤bi≤10^9) denoting the lexicographically smallest sequence.

对于每组数据, 输出n个整数b1,b2,...,bn (1≤bi≤10^9)表示那个字典序最小的序列.

 Sample Input

3
1
10
5
5 4 3 2 1
3
1 3 5

 Sample Output

1
1 1 1 1 1
1 2 3

 Problem Idea

解题思路:

【题意】
中文题面


【类型】
最长上升子序列

【分析】
一开始的时候还各种方法试来试去,结果自己的一组数据都过不了

后来才发现,原来这题就是求以ai结尾的最长上升子序列为多少

好吧,原来一直都是我想太多

于是乎,一个最长上升子序列模板搞定

【时间复杂度&&优化】
O(nlogn)

题目链接→HDU 5748 Bellovin

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 100005;
const int M = 1005;
const int inf = 1000000007;
const int mod = 1000000007;
int  a[N], f[N], d[N];    // f[i]用于记录 a[0...i]的最大长度
int bsearch(const int *f, int size, const int &a)
{
    int  l=0, r=size-1;
    while( l <= r )
    {
        int  mid = (l+r)>>1;
        if( a > d[mid-1] && a <= d[mid] )
            return mid;                // >&&<= 换为: >= && <
        else if( a <d[mid] )
                r = mid-1;
        else l = mid+1;
    }
}
int LIS(const int *a, const int &n)
{
    int  i, j, size = 1;
    d[0] = a[0]; f[0] = 1;
    for( i=1; i < n; ++i )
    {
        if( a[i] <= d[0] )             // <= 换为: <
            j = 0;
        else if( a[i] > d[size-1] ) // > 换为: >=
            j = size++;
        else
            j = bsearch(d, size, a[i]);

        d[j] = a[i]; f[i] = j+1;
    }
    return size;
}
int main()
{
    int  t,i,n;
    scanf("%d",&t);
    while(t--)
    {
        memset(f,0,sizeof(f));
        memset(d,0,sizeof(d));
        scanf("%d",&n);
        for( i=0; i < n; ++i )
            scanf("%d", &a[i]);
        LIS(a, n);
        for(i=0;i<n;i++)
            printf("%d%c",f[i],i!=n-1?' ':'\n');
    }
    return 0;
}


 Problem 1004 Dertouzos

Accept: 0    Submit: 0
Time Limit: 7000/3500 MS (Java/Others)    Memory Limit : 131072/131072 K (Java/Others)

 Problem Description

A positive proper divisor is a positive divisor of a number n, excluding n itself. For example, 1, 2, and 3 are positive proper divisors of 6, but 6 itself is not.

Peter has two positive integers n and d. He would like to know the number of integers below n whose maximum positive proper divisor is d.

正整数x称为n的positive proper divisor, 当且仅当x∣n并且1≤x<n. 例如, 1, 2, 和3是6的positive proper divisor, 但是6不是.

Peter给你两个正整数n和d. 他想要知道有多少小于n的整数, 满足他们的最大positive proper divisor恰好是d.

 Input

There are multiple test cases. The first line of input contains an integer T(1≤T≤10^6), indicating the number of test cases. For each test case:

The first line contains two integers n and d(2≤n,d≤10^9).
输入包含多组数据, 第一行包含一个整数T(1≤T≤10^6)表示测试数据组数. 对于每组数据:
第一行包含两个整数n和d(2≤n,d≤10^9).

 Output

For each test case, output an integer denoting the answer.

对于每组数据, 输出一个整数.

 Sample Input

9
10 2
10 3
10 4
10 5
10 6
10 7
10 8
10 9
100 13

 Sample Output

1
2
1
0
0
0
0
0
4

 Problem Idea

解题思路:

【题意】
中文题面


【类型】
素数表+暴力

【分析】
首先,我们要清楚,怎样的整数,它的最大positive proper divisor恰好是d

即kd除本身以外最大因子是d,故k≠1,其次,我们需要发现,k只能是小于等于(d的最小质因子)的质数

不信?比如d=100,那我k只能取2,如果k=7,kd=700,那positive proper divisor应该为350,显然矛盾

故令y=xd, 如果d是y的maximum positive proper divisor, 显然要求x是y的最小质因子. 令mp(n)表示n的最小质因子, 那么就有x≤mp(d), 同时有y<n, 那么. 于是就是计算有多少个素数x满足.

当d比较大的时候,比较小, 暴力枚举x即可. 当d比较小的时候, 可以直接预处理出答案.


【时间复杂度&&优化】
O(Tlogn)

题目链接→HDU 5750 Dertouzos

 Source Code

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 100005;
const int M = 32000;
const int inf = 1000000007;
const int mod = 1000000007;
int prime[N],p,min_factor[N];
bool v[N];
void get_prime()
{
    memset(v,false,sizeof(v));
    for(int i=2;i<N;i++)
        if(!v[i])
        {
            prime[p++]=i;
            for(int j=i;j<N;j+=i)
            {
                if(!v[j])
                    min_factor[j]=i;
                v[j]=true;
            }
        }
}
int main()
{
    int t,n,d,k,ans,i;
    p=0;
    get_prime();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&d);
        k=(n-1)/d;
        if(d>=N)
        {
            for(i=0;prime[i]<k;i++)
                if(d%prime[i]==0)
                {
                    k=prime[i];
                    break;
                }
        }
        else
            k=min(k,min_factor[d]);
        ans=upper_bound(prime,prime+p,k)-prime;
        printf("%d\n",ans);
    }
    return 0;
}

菜鸟成长记

关于 KFCOI Round #1 的具体资料并未在提供的引用中提及。然而,可以根据 Codeforces 类型的比赛结构以及类似的竞赛经验来推测可能的内容。 ### 参与 KFCOI Round #1 的相关信息 通常情况下,在线编程比赛(如 KFCOI 或 Codeforces)会提供以下资源供参赛者回顾: #### 1. **题目集** 比赛结束后,官方一般会在其官方网站或相关平台上发布完整的题目集合。这些题目可能会附带样例输入输出以便于理解问题的要求[^1]。 #### 2. **题解与思路分析** 官方或者社区成员往往会撰写详细的题解文档,帮助未通过某些难题的选手学习新的算法技巧。例如,在 Codeforces 中,像 A 到 D 题这样的解析是非常常见的。 #### 3. **比赛数据统计** 统计信息包括但不限于每位选手提交次数、正确率等指标。这类数据分析有助于评估个人表现并与他人对比进步空间[^3]。 #### 4. **赛后讨论论坛** 很多平台都设有专门区域让参与者自由交流想法甚至分享错误经历以互相借鉴成长。比如提到过的多次尝试不同方法解决同一道简单题目的过程就是很好的例子。 ### 如何获取上述材料? - 如果您已经注册参加了该赛事,则可以直接登录账户查看存档页面; - 对于公开可用的部分链接地址可以通过搜索引擎查询关键词“KFCOI Round #1 review”找到相关内容; - 加入一些活跃的技术社群也可能获得更多一手资讯和支持。 以下是基于假设场景下的 Python 实现示例用于处理类似 CF 圆整数分解成最小数量正整数组合的问题: ```python def min_sum_representation(n): result = "" current_value = n for digit in range(9, 0, -1): while current_value >= digit: result += str(digit) current_value -= digit return &#39;&#39;.join(sorted(result)) print(min_sum_representation(7)) # 输出:"7" ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值