伊蘇比的夢幻之旅(四)比賽題解

比賽地址:http://qscoj.cn/contest/28/c++

第13-1關 幹部競選(小數據)函數

分析:候選人的數量只有2,因此能夠設置一個布爾變量f1表示學生投票後的勝者,f2表示所有將票投給學生1後的勝者,f3表示所有將票投給全勝2後的勝者;若是f1,f2,f3又不相同的狀況的話,則說明老師投票對結果有影響,投票必須進行;若是三者相等則說明老師投票對結果沒影響,投票無須進行。大數據

標程:spa

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,a,b;
    bool f1,f2,f3;
    cin>>n>>m;
    cin>>a>>b;
    f1=(a>=b);
    f2=(a+m>=b);
    f3=(a>=b+m);
    if (f1==f2 && f2==f3) cout<<"No"<<endl;
    else cout<<"Yes"<<endl;
    return 0;
}

第13-2關 幹部競選(中數據)code

分析:候選人的數量只有8,老師的票數只有7;因此咱們能夠考慮全部的老師投票的狀況,再判斷對最後的排名結果有沒有影響,只要有一組與以前的排名不一樣,則說明老師投票能夠改變結果,必須進行。blog

標程:ci

#include<bits/stdc++.h>
using namespace std;
struct stu
{
    int a,id;
}p[10],q[10];
int n,m;
bool flag;
bool cmp(stu x,stu y)
{
    if (x.a!=y.a) return x.a>y.a;
    return x.id<y.id;
}
void dfs(int k)
{
    int i;
    if (k==m+1)
    {
        for(i=1;i<=n;i++)
            q[i]=p[i];
        sort(q+1,q+1+n,cmp);
        for(i=1;i<=n;i++)
            if (q[i].id!=p[i].id) flag=false;
        return ;
    }
    for(i=1;i<=n;i++)
    {
        p[i].a++;
        dfs(k+1);
        p[i].a--;
    }
}
int main()
{
    int i;
    cin>>n>>m;
    for(i=1;i<=n;i++)
    {
        p[i].id=i;
        cin>>p[i].a;
    }
    sort(p+1,p+1+n,cmp);
    flag=true;dfs(1);
    if (flag) cout<<"No"<<endl;
    else cout<<"Yes"<<endl;
    return 0;
}

 第13-3關 幹部競選(大數據)it

分析:由於本題要求只要一名同窗的票數可能發生變化,老師投票就應該進行。因此咱們能夠先把全部候選人進行完學生投票後排個序,再依次判斷第2我的能不能超過第1個,第3個能不能超過第2個,第N個能不能超過第N-1個,這些只要有一個知足就應進行老師投票,不然則沒必要。io

標程:class

#include<bits/stdc++.h>
using namespace std;
struct stu
{
    int a,id;
}p[100010];
bool cmp(stu x,stu y)
{
    if (x.a!=y.a) return x.a>y.a;
    return x.id<y.id;
}
int main()
{
    int n,m,i;
    bool flag;
    cin>>n>>m;
    for(i=1;i<=n;i++)
    {
        p[i].id=i;
        scanf("%d",&p[i].a);
    }
    sort(p+1,p+1+n,cmp);flag=true;
    for(i=2;i<=n;i++)
    {
        p[i].a+=m;
        if (p[i].a>p[i-1].a) flag=false;
        if (p[i].a==p[i-1].a && p[i].id<p[i-1].id) flag=false;
        p[i].a-=m;
    }
    if (flag) cout<<"No"<<endl;
    else cout<<"Yes"<<endl;
    return 0;
}

第14-1關 男女搭配(小數據)

分析:N的範圍只有2,爲1時答案就爲g(1)*l(1);爲2時判斷下g(1)*l(1)+g(2)*l(2)和g(1)*l(2)+g(2)*l(1)哪一個大就好。

標程:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,i,ans1,ans2,ans;
    int g[3],l[3];
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>g[i];
    for(i=1;i<=n;i++)
        cin>>l[i];
    if (n==1) ans=g[1]*l[1];
    else
    {
        ans1=g[1]*l[1]+g[2]*l[2];
        ans2=g[1]*l[2]+g[2]*l[1];
        ans=max(ans1,ans2);
    }
    cout<<ans<<endl;
    return 0;
}

第14-2關 男女搭配(中數據)

分析:N的範圍只有10,因此配對方式共有10!=3628800種狀況,咱們能夠放N個位置,保持男生的位置不變,經過next_permutation函數使女生的位置發生變化,而後從全部狀況中取最大值就行。

標程:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int l[12],g[12],a[12];
    int res,ans,n,i;
    cin>>n;ans=0;
    for(i=1;i<=n;i++)
        cin>>l[i];
    for(i=1;i<=n;i++)
        cin>>g[i];
    for(i=1;i<=n;i++)
        a[i]=i;
    do
    {
        res=0;
        for(i=1;i<=n;i++)
            res+=l[i]*g[a[i]];
        ans=max(res,ans);
    }while(next_permutation(a+1,a+1+n));
    cout<<ans<<endl;
    return 0;
}

第14-3關 男女搭配(大數據)

分析:若是咱們先把男生的紳士度從大到小排個序,再給男生選擇配對的女生的時候,按照貪心的思想,較大紳士度的男生確定應該搭配較大可愛度的女生,才能使總和最大。因此也應該將女生從大到小排個序,再將對應位置的男生女生進行配對,必定是最優解。注意一個問題,N的範圍爲1000,g(i)、l(j)的範圍爲10^8,總和最大可能達到10^19,超過了long long的範圍,因此應該使用unsigned long long.

標程:

#include<bits/stdc++.h>
using namespace std;
unsigned long long l[100010],g[100010];
int main()
{
    int i,n;
    unsigned long long ans;
    cin>>n;ans=0;
    for(i=1;i<=n;i++)
        scanf("%llu",&l[i]);
    for(i=1;i<=n;i++)
        scanf("%llu",&g[i]);
    sort(l+1,l+1+n);
    sort(g+1,g+1+n);
    for(i=1;i<=n;i++)
        ans+=l[i]*g[i];
    cout<<ans<<endl;
    return 0;
}

第15-1關 外國人排隊(小數據)

分析:這個問題考慮時咱們應該先將每一個位置放哪國人的方案數算出來再乘上各個國家在本身國家應在的位置上的全排列數。若是隻有兩個國家的人的話兩個國家的人數相差不能超過1,若是相差爲1,只有ABABABABA這一種狀況;若是相等,則有ABABABAB和BABABABA兩種狀況。再乘上兩個國家人數的階乘就是所求答案。

標程:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int i,a,b,c,ans;
    int jc[8];
    jc[0]=1;
    for(i=1;i<=7;i++)
        jc[i]=jc[i-1]*i;
    cin>>a>>b>>c;
    if (a==b) ans=2*jc[a]*jc[b];
    else if (abs(a-b)<=1) ans=jc[a]*jc[b];
    else ans=0;
    cout<<ans<<endl;
    return 0;
}

第15-2關 外國人排隊(中數據)

分析:人數總數不會超過21個,當咱們肯定了某個位置人的國籍後,下一我的的國籍最多有兩種狀況,因此採用DFS的方法是3*2^20的複雜度。經過DFS的方式將每一個位置是什麼國家人的方案數求出來,再乘以各個國家內部的全排列數就是答案。

標程:

#include<bits/stdc++.h>
using namespace std;
int c1,c2,c3;
int p[23];
int a,b,c,s;
long long ans;
int mod=1e9+7;
void dfs(int k)
{
    int i;
    if (k==s+1)
    {
        if (c1==a && c2==b && c3==c) ans++;
        return ;
    }
    for(i=1;i<=3;i++)
    {
        if (i==p[k-1]) continue;
        p[k]=i;
        if (i==1) {c1++;dfs(k+1);c1--;}
        if (i==2) {c2++;dfs(k+1);c2--;}
        if (i==3) {c3++;dfs(k+1);c3--;}
    }
}
int main()
{
    int jc[8],i;
    jc[0]=1;
    for(i=1;i<=7;i++)
        jc[i]=jc[i-1]*i;
    cin>>a>>b>>c;ans=0;s=a+b+c;
    dfs(1);
    ans*=jc[a];ans%=mod;
    ans*=jc[b];ans%=mod;
    ans*=jc[c];ans%=mod;
    cout<<ans<<endl;
    return 0;
}

第15-3關 外國人排隊(大數據)

分析:N的範圍爲77,確定不能採用像第15-2關那樣用DFS的方式去作,應用DP的方式進行轉移。咱們設置一個四維的DP,DP[i][j][k][x]表示當前有i個美國人,j個英國人和k個美國人且最後一位爲x國的方案數;x爲1表明美國人,爲2表明英國人,爲3表明法國人。由於任意兩個相鄰位置的人都不能是相同國家的,所以DP[i][j][k][1]能夠從DP[i-1][j][k][2]和DP[i-1][j][k][3]轉移而來;DP[i][j][k][2]能夠從DP[i][j-1][k][1]和DP[i][j-1][k][3]轉移而來;DP[i][j][k][3]能夠從DP[i][j][k-1][1]和DP[i][j][k-1][2]轉移而來。最後的答案就是DP[a][b][c][1]+DP[a][b][c][2]+DP[a][b][c][3].

標程:

#include<bits/stdc++.h>
using namespace std;
long long dp[80][80][80][4];
long long mod=1e9+7;
int main()
{
    int a,b,c,s;
    int i,j,k,r;
    long long jc[80],ans;
    cin>>a>>b>>c;s=a+b+c;
    for(r=1;r<=s;r++)
    {
        for(i=0;i<=a;i++)
            for(j=0;j<=b;j++)
            {
                    k=r-i-j;
                    if (k<0 || k>c) continue;
                    if (i)
                    {
                        if (r==1 && j+k==0) {dp[i][j][k][1]=1;continue;}
                        dp[i][j][k][1]+=dp[i-1][j][k][2];dp[i][j][k][1]%=mod;
                        dp[i][j][k][1]+=dp[i-1][j][k][3];dp[i][j][k][1]%=mod;
                    }
                    if (j)
                    {
                        if (r==1 && k+i==0) {dp[i][j][k][2]=1;continue;}
                        dp[i][j][k][2]+=dp[i][j-1][k][1];dp[i][j][k][2]%=mod;
                        dp[i][j][k][2]+=dp[i][j-1][k][3];dp[i][j][k][2]%=mod;
                    }
                    if (k)
                    {
                        if (r==1 && i+j==0) {dp[i][j][k][3]=1;continue;}
                        dp[i][j][k][3]+=dp[i][j][k-1][1];dp[i][j][k][3]%=mod;
                        dp[i][j][k][3]+=dp[i][j][k-1][2];dp[i][j][k][3]%=mod;
                    }
            }
    }
    ans=dp[a][b][c][1]+dp[a][b][c][2]+dp[a][b][c][3];ans%=mod;
    jc[0]=1;
    for(i=1;i<=77;i++)
    {
        jc[i]=jc[i-1]*i;
        jc[i]%=mod;
    }
    ans*=jc[a];ans%=mod;
    ans*=jc[b];ans%=mod;
    ans*=jc[c];ans%=mod;
    cout<<ans<<endl;
    return 0;
}
相關文章
相關標籤/搜索