123456梁静

导航

 

一、F题(签到)对答案一时爽

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
char aa[110];
char bb[110];
int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)cin >> aa[i];
    for (int i = 0; i < n; i++)cin >> bb[i];
    int cou = 0;
    for (int i = 0; i < n; i++) {
        if (aa[i] == bb[i])cou++;
    }
    int p1 = n + cou;
    int p2 = 0;
    cout << p1 << " " << p2 << endl;

}
View Code

 

二、B题 括号

链接:https://ac.nowcoder.com/acm/contest/9981/B
题目描述  
请你构造一个非空的括号字符串,包含正好 kkk 个不同合法括号对。
所谓括号字符串,是指由'('和')'这两种字符构成的字符串。
要求构造的字符串长度不超过100000。
输入描述:
一个整数 k。
k小于10^9.
输出描述:
一个仅包含左右括号字符串,其中有 k个合法的括号对。如果有多种构造方法,输出任意一种合法即可。
理解:WA一次,是没有看到字符串不能超过10^5,后来想到卡长度应该不会超,所以我就想直接对半分,左边全部都是 ( ,右边全部都是 ) ,其他的从后面数过来,只要再添加一个(。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;

int main() {
    int k;
    cin >> k;
    if (k < 99999) {
        cout << "(";
        for (int i = 0; i < k; i++)cout << ")";
        cout << endl;
    }
    else {
        int p = k / 50000;
        int pp = k % 50000;
        for (int i = 0; i < p; i++)cout << "(";
        int ppp = 50000 - pp;
        for (int i = 0; i < ppp; i++)cout << ")";
        cout << "(";
        //cout << p << " " << pp << " " << ppp << endl;
        for (int i = 0; i < pp; i++)cout << ")";
    }
}
View Code

 

三、I题 限制不互素对的排列(中思维)

链接:https://ac.nowcoder.com/acm/contest/9981/I
题目描述  :输入一个数 ,请构造一个长度为  n 的排列,使得其中正好有 k  对相邻的数gcd(最大公约数)大于1  。
排列是指  1到  n 一共  n  个数,每个数都出现过且仅出现过 1  次。n<10^5,0<k<n/2.
输入描述:
两个整数  n 和 k  ,用空格隔开。
输出描述:
如果不存在可行的构造方案,输出-1。
否则输出一行 n个数符合的排列,用空格隔开。如果有多组可行的构造方案,输出任意一组即可。
理解:取巧,0<k<n/2,只要想到k的范围的含义,就能够想出来,全部都都是2的倍数不就可以破解很多了。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
int n, k;
int aa[100010];
int main() {

    cin >> n >> k;

        if (k == n / 2){
            if (n < 6)cout << -1 << endl;
            else {
                for (int i = 2; i <= 2 * k; i = i + 2) {
                    if (i == 6)continue;
                    cout << i << " ";
                    aa[i] = 1;
                }
                aa[6] = 1;
                aa[3] = 1;
                cout << 6 << " " << 3 << " ";
                for (int i = 1; i <= n; i++) {
                    if (aa[i] == 0)cout << i << " ";
                }
            }
        }
        else {
            for (int i = 2; i <= 2 * (k+1); i = i + 2) {
                cout << i << " ";
                aa[i] = 1;
            }
            for (int i = 1; i <= n; i++) {
                if (aa[i] == 0)cout << i << " ";
            }
        }
    
}
View Code

 

四、A题 串(组合数学)
链接:https://ac.nowcoder.com/acm/contest/9981/A
题目描述 : 长度不超过n,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对10^9+7取模
所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。
例如,"unoacscc"包含子序列"us",但"scscucu"则不包含子序列"us"
输入描述:一个正整数n(2≤n≤10^6 )
输出描述:一个正整数,为满足条件的字符串数量对10^9+7取模的值
输入
3
输出
77
说明
长度为3的字符串里,
形状是"u?s"的共有26个
形状是"?us"的共有26个
形状是"us?"的共有26个。
但是,"uss"和"uus"被各多计算了1次,应该减去,
所以共有26*3-2=76个。
再加上长度为2的"us",所以长度不超过3的合法字符串共有77个。
示例3
输入
874520
输出
16471619
理解1:(状态DP)
既然我们需要前i-1个有u没有s的,就把所有点情况都放在状态里, f[i][0/1/2]表示长度为i的 **没有u的串/有u但是u后面没有s的串/有us的串的数量**
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
int n;
ll f[1000100][4];
const int mod = 1e9 +7;


int main() {
    ll ans = 0;
    cin >> n;
    f[1][0] = 25;
    f[1][1] = 1;
    f[1][2] = 0;
    for (int i = 2; i <= n; i++) {
        f[i][0] = (f[i - 1][0] * 25) % mod;
        f[i][1] = (f[i - 1][1] * 25 + f[i - 1][0]) % mod;
        f[i][2] = (f[i - 1][1] + f[i - 1][2] * 26) % mod;
        ans = (ans + f[i][2]) % mod;
    }
    cout << ans ;
}
View Code

理解2:(组合数学)

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
int n;
ll f[1000009];//数组也要是long
const int mod = 1e9 +7;

ll qu(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1)res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res ;
}

int main() {
    cin >> n;
    ll res = 1;
    f[2] = 1;
    for (int i = 3; i <= n; i++) {
        f[i] = (f[i - 1] * 25 % mod + qu(26, i - 1)) % mod;
        f[i] = f[i] - qu(25, i - 1);
        if (f[i] < 0)f[i] = f[i] + mod;//注意:要加上取模
        res = ( res + f[i]) % mod;

    }
    cout << res;
}
    
View Code
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
int n;
ll aa[1000100];
const int mod = 1e9 +7;
 
ll qu(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1)res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
 
int main() {
    scanf("%d", &n);
    aa[2] = 1;
    aa[3] = 77;
    for (int i = 3; i <= n; i++) {
        aa[i] = (qu(26, i - 1) - qu(25, i - 1) + 25 * aa[i - 1]) % mod;
        if(aa[i]<0)aa[i]+=mod;//就是这里导致我写的过不了
    }
    ll ans = 0;
    for (int i = 2; i <= n; i++) {
        ans = (ans + aa[i]) % mod;
    }
    ans = ans % mod;
    printf("%d", ans);
}
View Code

 

五、三棱锥之刻(计算几何,正三棱锥)

链接:https://ac.nowcoder.com/acm/contest/9981/E
牛牛站在一个棱长为的正三棱锥内部的中心。(牛牛是不可移动的)
(所谓正三棱锥,指六条棱都相等的三棱锥。正三棱锥的中心指到 4 个顶点距离都相等的那个点)
如上图,,牛牛站在P点,
他拿着一个染色喷雾,可以用来给正三棱锥的内表面染色。
已知喷雾能喷洒的距离为。也就是说,三棱锥内表面距离牛牛不超过的点才有可能被染色。牛牛想知道,正三棱锥内表面能被他染色的最大面积是多少?
ps:牛牛可看成一个无大小的点。重力对于喷雾的影响忽略不计。
输入描述:两个正整数和
1≤a,r≤1000
输出描述:染色的最大面积。若你的答案和正确答案误差不超过10^-3,则认为你的答案正确。
示例1
输入
1 1
输出
1.73205
说明:正三棱锥棱长为 1 ,且喷雾的有效射程为 1 ,易知牛牛可以将喷雾喷满整个内表面,即结果为整个内表面的面积。

理解:正三棱锥:内切球半径   r =a*(根号6)/12        外接球半径  R  = a*(根号6)/4    中心到面的距离   H=a*(根号3)/6    扇形面积 S=0.5*弧度*直线长*直线长

#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 7;
const double pi = acos(-1);//3.14159
//3.1415926535   897932384626  43383279502  88419716939937
//     5105820974944592307   8164062862089986  2803482534211706798

double cal(double a, double b, double c) {
    double tmp = (a * a + b * b - c * c) / (2 * a * b);
    return acos(tmp);
}

double a, r;
int main() {
    cin >> a >> r;

    double minr = sqrt(6) / 12 * a;//内切球半径
    double maxr = sqrt(6) / 4 * a;//外接球半径
    double ans = 0;
    if (r <= minr)ans = 0.0;
    else if (r >= maxr)ans = a * a * sqrt(3);
    else {
        double R = sqrt(r * r - minr * minr);//三角形染色的圆的半径
        double h = sqrt(3) / 6 * a;//正三角形的内圆半径,高的1/3
        if (R <= h)ans = 4 * (pi * R * R);
        else {
        //R比较大的时候,超过h,小于maxr的时候圆只有一部分在染色
        //所以先求出整个圆的面积,减去大扇形面积,加会大扇形里面的三角形面积
        //求三角形DEJ的大角弧度,EJ就是mn
            ans = pi * R * R;
            double mn = 2 * sqrt(R * R - h * h);
            double hudu = cal(R, R, mn);//弧度
            ans -= 3 * (0.5 * hudu * R * R);//扇形面积
            ans += 3 * (0.5 * R * R * sin(hudu));//正弦定理
            ans *= 4;
        }

    }

    cout << ans << endl;
}
View Code

 

 

 

 

 

posted on 2021-02-04 22:34  123456梁静  阅读(63)  评论(0)    收藏  举报