牛客练习赛113

A. 小红的基环树

A-小红的基环树_牛客练习赛113 (nowcoder.com)

题目: 定义基环树为n个节点、n条边的、没有自环和重边的无向连通图。

定义一个图的直径是任意两点最短路的最大值。

小红想知道,n个节点构成的所有基环树中,最小的直径是多少?

思路:由题意观察可以知道,当n等于3时,最小的直径就是1,而当n大于等于4时,直径等于2.

代码:

#include 
using namespace std;

int main()
{
    int n;
    cin >> n;
    
    if(n == 3) cout << 1 << endl;
    else cout << 2 << endl;
    return 0;
}

B.小红的回文串

B-小红的回文串_牛客练习赛113 (nowcoder.com)

题目:
小红拿到了一个字符串,字符串仅由小写字母和'?'字符组成。
小红会将每个'?'替换成任意小写字母。她希望最终字符串变成回文串。
小红想知道,有多少种不同的方案?答案请对10^9 + 7取模。

思路:由于是判断回文串,可以利用l, r作为左右对应位置的下标来遍历,然后就分为两种情况,分别s[l] == s[r] 和 s[l] != s[r]来考虑.

注意:因为结果要对10^9 + 7去模,为了防止数据过大的情况发生,所以我们在循环中需要时刻对res取模。

代码:

#include 
using namespace std;
 
typedef long long ll;
 
string s;
ll mod = 1e9 + 7;
 
int main()
{
    string s;
    cin >> s;
 
    int l = 0;
    int r = s.size() - 1;
 
    ll res = 1;
 
    while (l <= r)
    {
        if (s[l] == '?' && s[r] == '?') {
            res = (res *26) % mod;
        }
        if (s[l] != s[r]) {
            if(s[l] == '?' || s[r] == '?') ;
            else res = 0;
        }
        l++;
        r--; 
    }
     
    cout << res % mod << endl;
    return 0;
}

C.小红的数组操作(easy版)

C-小红的数组操作(easy version)_牛客练习赛113 (nowcoder.com)

题目:


小红拿到了一个数组,她可以进行若干次以下操作:

1.选择一个元素,花费p,使其加x。
1.选择一个元素,花费q,使其减y。

小红希望若干次操作后,数组的平均数是一个整数。你能帮小红求出最小的总代价吗?

思路:由于我们不知道p,q哪个更贵,所以我们在满足条件的情况下需要一层一层遍历求最小值。

由于题目规定了x一定为1,所以很好处理。

代码:

#include
#include

using  namespace std;
const int N = 100010;
int a[N];
int main() 
{
    long long n, p, x, q, y;
    cin >> n >> p >> x >> q >> y;
    long long sum = 0;
    for(int i = 0; i < n; i++){
    cin >> a[i];
    sum += a[i];
    }
    
    sum %= n;
    long long ans = 1e18;
    
    for(int i = 0 ;i < n; i++){
        long long c = i * y % n;
        long long s = (n - (( sum - c ) % n)) % n;
        ans=min(ans,i * q + s * p);
         
    }
    cout<

以下是我写错的代码:

#include 
#include 
using namespace std;

int main()
{
    int n, p, x, q, y;
    cin >> n >> p >> x >> q >> y;
    int nums = 0;
    int a;
    for (int i = 0; i < n; i++) cin >> x, nums += x;

    int k = nums % n;

    int add = (n - k) * p;

    int numy = 0;
    while (k > 0)
    {
        k -= y;
        numy++;
    }

    int sub = numy * q + abs(k) * p;
    int mi = min(add, sub);

    cout << mi << endl;
    return 0;
}

从上面的sub和add可以看出来,我这里是用我自以为的可能的题目所要求的值来进行比较最小值。但忽略了一个点:就是可能p非常大,而q非常小。所以我们需要尽可能部去用q,而不去用p。所以我们需要一层一层遍历比较得到最小值。而不是当k一旦小于0用x=1来填补的值作为可能的最小值。

你可能感兴趣的:(算法)