FBI_一起來玩呀3—— [B-C-D]

問題蟲洞——B:B - Make Product Equal One

 

黑洞內窺:

給出一個n個數的序列, 你每次可以花費 1 money 使得序列中的某個數+1或-1.

求讓序列的乘積之和爲1的最小花費。

 

思維光年:

-1要成對出現,1就不用管,0可以算做一個-1或1

暴力就好了啦!!!

 

ACcode:

#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define MAXN 100005
#define INF 0x3f3f3f3f//將近int類型最大數的一半,而且乘2不會爆int
#define MOD 1000000007 // MOD%4 = 3
const double pi = acos(-1.0);
const double eps = 1e-6;

int a[MAXN];
int main()
{
    int n, ans=0, cnt=0, tem=0;
    ll sum=0;
    cin >> n;
    for(int i=0; i<n; ++i)
        scanf("%d", &a[i]);
    //sort(a, a+n);
    for(int i=0; i<n; ++i)
    {
        if(a[i] == 0)
        {
            sum++;
            ans++;
        }
        else if(a[i] < -1 || a[i] == -1)
        {
            cnt++;
            sum+=(-1 - a[i]);
        }
        else if(a[i] > 1)
        {
            tem++;            //其實這裏沒用。。。
            sum+=(a[i] - 1);
        }
    }
    //ans = ans+cnt;
    if(ans > 0 || cnt%2 == 0)
        cout << sum << '\n';
    else
        cout << sum+2 << '\n';
    return 0;
}

 

問題蟲洞——C: C - Almost Equal

 

黑洞內窺:

輸入n,給出1~2n的數,將這2n個數圍成一個圈,

使得每n個數之間的和兩兩不能相差超過1.

若無這樣的序列,輸出NO

有則輸出YES,且輸出這樣的一個序列。

 

思維光年:

根據樣例,猜出偶數時爲NO,奇數時爲YES

然後肯定是有規律的,推出來就是。。

將數字這樣放,然後先全部輸出上面的再全部輸出下面的,,就是答案了;

 

ACcode:

#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define MAXN 100005
#define INF 0x3f3f3f3f//將近int類型最大數的一半,而且乘2不會爆int
#define MOD 1000000007 // MOD%4 = 3
const double pi = acos(-1.0);
const double eps = 1e-6;

int a[MAXN], b[MAXN];
int main()
{
    int n;
    cin >> n;
    if(n%2 == 0) puts("NO");
    else {
        puts("YES");
        int c = 2, d = 1, ans = 0;
        a[1] = 1;
        for(int i=2; i<=2*n-1; ++i)
        {
           if(ans < 2)
           {
               b[d] = i;
               d++;
               ans++;
           }
           else if(ans < 4)
           {
               a[c] = i;
               c++;
               ans++;
           }
           if(ans == 4)
            ans = 0;
        }
        b[n] = 2*n;
        for(int i=1; i<=n; ++i)
            cout << a[i] << ' ';
        for(int i=1; i<=n;  ++i)
        {
            cout << b[i];
            if(i!=n) cout << ' ';
            else cout << '\n';

        }
    }
    return 0;
}

 

問題蟲洞——D:D - Shortest Cycle CodeForces - 1206D

 

黑洞內窺:

給出n個數,如果如果i!=j且(a[i]&a[j])!=0,則在i與j之間建邊


求圖的最小環 (無向圖最小環至少三個頂點)

 

思維光年:

(我讀題的時候還在納悶爲什麼2不可以。。。。) 還是太菜

理性的求解:

如果二進制位的某一位爲1的數的數量>=3那麼答案就是3(因爲這樣就證明了至少有三個點有邊)


如果都不爲3,則不爲0的數最多隻有2*63=126個(long long只有63位有效)

所以如果不爲0的數大於126個答案就是3了。。。因爲每一位上都有1.


否則直接用Floyd暴力最小環就行了;

 

ACcode:

#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define MAXN 200
#define INF 300//將近int類型最大數的一半,而且乘2不會爆int
#define MOD 1000000007 // MOD%4 = 3
const double pi = acos(-1.0);
const double eps = 1e-6;

ll a[100005];
int g[MAXN][MAXN], d[MAXN][MAXN], ans=INF;
int main()
{
    int n, tot=0;
    cin >> n;
    for(int i=1; i<=n; ++i)
    {
        ll x;
        scanf("%lld", &x);                //0不重要。因爲0不可能和任何點建邊。
        if(x) a[++tot] = x;
    }
    if(tot > 63*3) puts("3");
    else
    {
        for(int i=1; i<=tot; ++i)            //建圖
            for(int j=1; j<=tot; ++j)
                if(a[i]&a[j])
                    g[i][j]=g[j][i]=d[i][j]=d[j][i]=1;
                else
                    g[i][j]=g[j][i]=d[i][j]=d[j][i]=INF;
        for(int k=1; k<=tot; ++k)           //Floyd求最小環
        {    
            for(int i=1; i<=k-1; i++)
                for(int j=i+1; j<=k-1; j++)
                    ans = min(ans, d[i][j]+g[i][k]+g[k][j]);
            for(int i=1; i<=tot; ++i)
                for(int j=1; j<=tot; ++j)
                    d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
        }
        if(ans == INF) puts("-1");
        else printf("%d\n", ans);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章