第六屆浙江省賽題解(部分)

第六屆浙江省賽題解

A. Second-price Auction

題目鏈接

題目大意

有n個投標者,投標最高的獲得物品,需要支付第二投標者的價格.

解題思路

使用結構體,保存投標的價格和一開始的排序.
然後根據投標價格排序,使用sort就可以了

AC代碼

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 110;
struct node
{
    int n, w;
}a[maxn];
bool cmp (node a, node b){
    if(a.w != b.w)
        return a.w < b.w;
    else
        return a.n > b.n;
}
int main()
{
    int T;
    int n;
    cin >> T;
    while(T--)
    {
        memset(a, 0 ,sizeof(a));
        cin >> n;
        for(int i=1; i<=n; i++){
            cin >> a[i].w;
            a[i].n = i;
        }
        sort(a+1, a+n+1, cmp);
        cout << a[n].n << ' ' << a[n-1].w << endl;
    }
    return 0;
}

B.Light Bulb

題目鏈接

題目大意


給你HhD ,求陰影部分L 的最大長度

解題思路


因爲Hh ,是固定的長度的,首先延長邊,根據邊的比例能夠退出x+y的函數表達式(用θ表示)
列出兩個極端的情況,人在最左邊和最右邊,這就是θ的取值範圍,然後對上面的函數表達式求導,得到函數是先增後減的,有極大值
求出零點θ的值(二分),然後判斷3點的值的最值即可

AC代碼

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
double H,D,h;
double mid;
bool judge(double mid) {
    double Sin = sin(mid);
    Sin = Sin * Sin;
    double Cos = 1.0-Sin;
    double ans = D/Sin - (H-h)/Cos;
    if(ans < 0) return false;
    return true;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%lf%lf%lf",&H,&h,&D);
        double l = atan(D/H), r = atan(D/(H-h));
        for(int i=0; i<1000; i++) {
            mid = (l+r)/2.0;
            if(judge(mid))
                l = mid;
            else r = mid;
        }
        double ans = max( (D*h/H), h);
        double tanx = H - (D/tan(mid)) + (tan(mid)*(h-H)) + D;
        ans = max(ans, tanx);
        printf("%.3f\n", ans);
    }
    return 0;
}

C.Connect them

題目鏈接

題目大意

N 臺計算機,要建立小型局域網,所有連接都是雙向的。兩臺計算機的鏈接成本是Cij ,找到最小的成本的連接方法

解題思路

一個最小生成樹的模板題目。但是他要輸出最小的字典序。
最簡單的方法是輸出邊的時候排序。
但是,如果生成樹不是一條的話就很難弄了。
所以我們可以吧輸入的數據,先排序,首先根據費用排序,然後根據起點排序,最後根據終點排序。

AC代碼

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10000+10;
struct Node{
    int s,e;
    int sum;
}node[maxn];
struct MP{
    int x,y;
}mp[maxn];
bool cmd1(MP a,MP b){
    if(a.x == b.x) return a.y < b.y;
    else return a.x<b.x;
}
bool cmd(Node a,Node b){
    if(a.sum != b.sum) return a.sum < b.sum;
    if(a.s != b.s) return a.s < b.s;
    return a.e < b.e;
}
int pre[maxn];
int p=0,n,pp=0;
int Find(int root){
    return pre[root]==root?root:Find(pre[root]);
}
int kruskal() {
    int ans = 0;
    for(int i = 1; i <=n ; i++) pre[i] = i;
    sort(node,node+p,cmd);
    pp = 0;
    for(int i = 0; i < p; i++) {
        int x = Find(node[i].s);
        int y = Find(node[i].e);
        if(x != y) {
            mp[pp].x = node[i].s;
            mp[pp++].y = node[i].e;
            ans ++;
            pre[y] = x;
        }
    }
    return ans;
}

int main(){
    int t;
    while(~scanf("%d",&t)){
        while(t--){
            scanf("%d",&n);
            p = 0;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    int x;
                    scanf("%d",&x);
                    if(x!=0){
                        node[p].s = i;
                        node[p].e = j;
                        node[p++].sum = x;
                    }
                }
            }
            int q = kruskal();
            if(q == 0 || q != n-1){
                printf("-1\n");

            }else{
                sort(mp,mp+pp,cmd1);
                for(int i=0;i<pp;i++){
                    printf("%d %d%c",mp[i].x,mp[i].y,i==pp-1?'\n':' ');
                }
            }
        }
    }
    return 0;
}

F.80ers’ Memory

題目鏈接

題目大意

看輸入輸出就可以看出.問每個人有幾個關鍵字在典型的80年代關鍵詞中

題解思路

使用map直接存儲字符串,然後直接找就好了

AC代碼

#include<cstdio>
#include<algorithm>
#include<map>
#include<string>
#include<iostream>
using namespace std;
map<string,int> mp;
int main(){
    int t;
    scanf("%d",&t);
    string s;
    for(int i=0;i<t;i++){
        cin>>s;
        mp[s] = 1;
    }
    int n,p;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&p);
        int sum=0;
        for(int j=0;j<p;j++){
            cin>>s;
            if(mp[s]==1) sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}

I.A Stack or A Queue?

題目鏈接

題目大意

給你一個輸入序列一個輸出序列,問是queue還是stack,還是都不或者都不是

解題思路

直接模擬,拿輸出序列和queue還有stack輸出對比

AC代碼

#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int maxn = 100+10;
int a[maxn],b[maxn];
queue<int> q;
stack<int> s;
int main(){
    int t;
    while(~scanf("%d",&t)){
        while(t--){
        while(!q.empty()) q.pop();
        while(!s.empty()) s.pop();
            int n;
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                int x;
                scanf("%d",&x);
                q.push(x);
                s.push(x);

            }
            int flag1,flag2;
            flag1=flag2=1;
            for(int i=0;i<n;i++){
                int x;
                scanf("%d",&x);
                if(x==q.front()){
                    q.pop();
                }else{
                    flag1=0;
                }
                if(x==s.top()){
                    s.pop();
                }else{
                    flag2=0;
                }
            }
            if(flag1==1 && flag2==1){
                printf("both\n");
            }else if(flag1==1 && flag2==0){
                printf("queue\n");
            }else if(flag1==0 && flag2 == 1){
                printf("stack\n");
            }else{
                printf("neither\n");
            }
        }
    }
    return 0;
}

K.K-Nice

題目鏈接

題目大意

構造出一個點的值等於周圍四個點的值的和(注:一定是四個點,挨着邊的都不算

解題思路

構造題一般都不是一個解,只要符合題目就行。
因爲一個點的值等於周圍四個點的值的和,所以當都是0時也是符合條件的,題目的樣例中也給出了這種情況,這種也是最好構造的.
我們可以從上到下,除了邊上點,其餘的符合條件的地方使用0,後面不符合條件的用1來填充。
注意最後的空格和換行,不然會WA

AC代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 17;
int num[maxn][maxn];

void tian(int n, int m, int k)
{
    if(m < 3){
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                num[i][j] = 0;
            }
        }
    }
    else{
        int number = k/(m-2);
        int i;
        for(i=1; i<=number+1; i++){
            for(int j=0; j<m; j++){
                num[i][j] = 0;
            }
        }
        if(k % (m-2) != 0){
            for(int j=0; j<= (k%(m-2)); j++){
                num[i][j] = 0;
            }
            for(int j=(k%(m-2))+1; j < m; j++){
                num[i][j] = 1;
            }
            i++;
        }
        for(;i < n; i++){
            for(int j=0; j<m; j++){
                num[i][j] = 1;
            }
        }
    }

}

int main()
{
    int T;
    int n, m , k;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d %d", &n, &m, &k);
        tian(n, m, k);
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                printf("%d%c", num[i][j],j==m-1?'\n':' ');
            }

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