天天看点

Codeforces Round330 Div2题解

这次太狗血了,进行到一半结果C题有问题unrated了。

A题不写了,比较简单

B. Pasha and Phone

大意就是给长度为n的数,分为n/k部分,即每部分k个digit,所以总共有n/k个k位数。对于第i个数,求能被Ai整除,且不以Bi开头的数的个数。求这个n位数可能的情况。

可以看到总的情况ans = ans1 * ans2 * … ans(n/k)。

分别求每一小部分的可能情况即可, 即求k位数能背中能被A整除又不以B开头的数,其中能被A整除的个数为tot = (10^k - 1)/A + 1,整数除法。以B开头的能被A整除的最小数为 num1 = (B * 10^(k - 1) / A)向上取整 * A,以B开头的能背A整除的最大数为 num2 = ((B+1) * 10^(k - 1) - 1) / A * A,整数除法。如果num1 <= num2,则tot减去(num2 - num1) / A + 1,代码

#define FOR(a, b, n) for(int (a) = (b); (a) < (n); ++(a))
#define ITE(a, v) for(auto (a) = v.begin(); (a) != v.end(); ++(a))
#define LL long long
#define ALL(v) v.begin(),v.end()
#define ZERO(v) memset(v, 0, sizeof v)
#define NEG(v)  memset(v, -1, sizeof v)
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MOD 1000000007
#define PI 3.141592653589793
inline long double min(long double a , long double b) {if(a < b)return a; return b;}
inline long double max(long double a , long double b) {if(a < b)return b; return a;}

int n;
int k;
int b[];
int a[];
int powTen(int kk)
{
    int res=  ;
    while(kk)
    {
        res *= ;
        kk--;
    }
    return res;
}
LL solve(int index)
{
    int aa = a[index];
    int bb = b[index];
    int end = powTen(k) - ;
    end = end/aa * aa;
    int tot = end / aa + ;
    int start = bb * powTen(k - );
    end = (bb + ) * powTen(k - ) - ;
    end = end / aa * aa;
    if(start % aa != )
        start = (start / aa + ) * aa;
    if(end >= start)
    {
        tot -= (end - start) / aa;
        tot--;
    }
    return tot;
}
int main(){

    cin >> n;
    cin >> k;
    FOR(i,,n/k)
    scanf("%d", &a[i]);
    FOR(i,,n/k)
    scanf("%d", &b[i]);
    LL res = ;
    FOR(i,,n/k)
    {
        res *= solve(i);
        res %= MOD;
    }
    cout << res << endl;
    return ;
}
           

C. Warrior and Archer

题目意思是有N个数,A和B每次选一个去除,直到剩2个,A和B都做出最优选择的话最后结果是一定的,问最后两个数之间的距离。

这题比赛的时候是N为任意,但是因为N奇数的时候好像答案有问题,现在重新post出来的时候已经定义N为偶数了,那这样就简单了。

先sort arr,然后设P=min{arr[i + n / 2] - arr[i]}。我们设最后的结果为ans,然后证明P即为ans。因为首先很显然P是小于等于ans的,假设arr[I + n / 2] - arr[I] == P,则对于warrior来说,他只要保证将j < I 以及 j > I + n / 2的值全部删去就可以,如果Archer中间捣乱删除了warrior本来应该删除的,那么warrior就删除掉arr[I]或者arr[I + n / 2],这样结果就比P小了。

ans也肯定是大于等于P的,我们将n-2次选择看成(n - 2) / 2次回合,每一回合warrior先选,对于Archer来讲,无论warrior先选什么,假设其选J,archer只要选对应的J + n / 2或者 J - n / 2即可,最后剩余的一对一定大于等于P。

综上,ans=P = min{arr[i + n / 2] - arr[i]}

代码很简单了,就不贴了

D. Max and Bike

题意大概就是自行车轮子上有标记,车位置任意(起点之前),从标记与起点重合开始计时,到标记与终点重合结束,求这段时间的最小值。

假设从开始到结束标记转了T圈,T为浮点数,T的整数部分时间肯定是确定的,2*PI*R/V*int(T)。现在考虑小数部分t,t可以转化为a, a代表转得角度,在这段时间内走得距离D=(f-s-int(T)*2*PI*R)是一定的,如何使t尽量小?这样就只能走圆的上方最快,因为速度是一定的,额外的速度来自于标记跟随圆运动时的水平速度,圆上方时这个分量是最大的,所以画图可以知道sin(a/2)*2+t*2*PI*R等于D,二分确定t的最小值即可

#define FOR(a, b, n) for(int (a) = (b); (a) < (n); ++(a))
#define ITE(a, v) for(auto (a) = v.begin(); (a) != v.end(); ++(a))
#define LL long long
#define ALL(v) v.begin(),v.end()
#define ZERO(v) memset(v, 0, sizeof v)
#define NEG(v)  memset(v, -1, sizeof v)
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MOD 1000000007
#define PI 3.141592653589793
inline long double min(long double a , long double b) {if(a < b)return a; return b;}
inline long double max(long double a , long double b) {if(a < b)return b; return a;}

int n;
int r;
int v;
double s,f;
int fff;
int sss;
double ff(double val)
{
    return  * sin(val) * r +  * val * r;
}
double solve()
{

    s = sss;
    f = fff;
    double circle =  * PI * r;
    double roundTime = circle / v;
    double res = ;
    double times = (f - s) / circle;
    int timesInt = times;
    f -= timesInt * circle;
    res += roundTime * timesInt;
    double dis = f - s;
    double l = ;
    double h = PI;
    //cout << dis << " " << res << endl;
    for(int i = ; i < ; i++)
    {
        double m = (l + h) / ;
        if(ff(m) > dis)
            h = m;
        else
            l = m;
    }
    //cout << l / 2 / PI * 360 << endl;
    res +=  * l * r / v;
    return res;

}
int main(){

    cout << setprecision();
    cin >> n;
    cin >> r >> v;
    FOR(i,,n)
    {
        scanf("%d%d", &sss, &fff);
        cout << solve () << endl;
    }
    return ;
}
           

E. 没做出来,做了再更新