西南民族大学第十一届程序设计竞赛(同步赛)(回顾补题)

先贴一波官方题解 这次比赛一道贪心原题,一道矩阵快速幂模板题,总体难度一般,不会的知识点 尺取,树形依赖背包

大模拟没写出来,可惜可惜

A 川川教练的困惑

直接暴力模拟

#include<bits/stdc++.h>
using namespace std;
vector<int> p;
bool cmp(int a,int b) {
    return a>b;
}
int main() {
    int n,m;
    scanf("%d%d",&n,&m);
    p.resize(n);
    for(int i=0;i<n;i++) {
        scanf("%d",&p[i]);
    }
    sort(p.begin(),p.end(),cmp);
    int sum=p[0]+p[1]+p[2];
    if(sum>m)
        printf("%d\n",sum);
    else
        printf("Waiver!");
    return 0;
}

B 都说小镇的切糕贵

首先让我们找出所有不同的字母,它们存在于给定的字符串中。我们首先遍历字符串找到所有不同的字符数量,利用map和尺取维护这个数量,然后更新答案即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
map<char, int> mp; 
int main() {
    int n;
    char s[maxn];
    while(~scanf("%d", &n)){
        mp.clear();
        scanf("%s", s + 1);
        for(int i = 1; i <= n; i++)
            mp[s[i]]++;
        int num = mp.size();
        int ans = n;
        int l = 1, r = 1;
        int now = num;
        mp.clear();
        while(mp.size() != num) {
            mp[s[r]]++;
            r++;
        }
        r--;
        while(l <= n - num + 1 && r <= n) {
            if(now == num) {
                ans = min(ans, r - l + 1);
                mp[s[l]]--;
                if(mp[s[l]] == 0)
                    now--;
                l++;
            }
            if(now < num) {
                r++;
                if(mp[s[r]] == 0)
                    now++;
                mp[s[r]]++;
            }
        }
        printf("%d\n", ans);
    }
}

C Guard the empire

原题,经典贪心,区间贪心需要进行转换。细节见代码

/*
首先求出在x轴上可以设立雷达并投射到某一个岛的区间
之后对于每个区间寻找公共部分,如果存在公共部分,更新
公共部分的尾部,如果不存在,雷达站设立的点数+1 
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int MAXN=1011;
struct node{
	double l,r;
};
vector<node> p;
bool cmp(node a,node b) {
	if(a.l==b.l)
		return a.r<b.r;
	else
		return a.l<b.l;
}
int main(){
	int n,cnt=1;
	double d;
	while(~scanf("%d%lf",&n,&d)) {
		if(n==0&&d==0)
			break;
		p.clear();
		bool flag=true;
		for(int i=0;i<n;i++) {
			double x,y;
			scanf("%lf%lf",&x,&y);
			if(abs(y)>d)
				flag=false;
			else {
				node temp;
				temp.l=x-sqrt(d*d-y*y);
				temp.r=x+sqrt(d*d-y*y);
				p.push_back(temp);
			}
		}
		printf("Case %d: ",cnt++);
		if(!flag) {
			puts("-1");
			continue; 
		} else {
			sort(p.begin(),p.end(),cmp);
			int ans=1;
			double start=p[0].r; 
			for(int i=1;i<n;i++) {
				if(start>=p[i].l)
					start=min(start,p[i].r);
				else {
					start=p[i].r;
					ans++;
				}
			}
			printf("%d\n",ans);
		}
	}
	return 0;
} 

D kth的自拍照

模拟

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1011;
int mat[MAXN][MAXN];
int main() {
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            scanf("%d",&mat[i][j]);
        }
    }
    for(int i=0;i<n;i++) {
        for(int j=n-1;j>=0;j--) {
            if(j==(n-1))
                printf("%d",mat[j][i]);
            else
                printf(" %d",mat[j][i]);
        }
        printf("\n");
    }
    return 0;
}

E HJ又种花啦

找规律,比较简单

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    int min1=min(n,m),maxn1=max(n,m);
    if(min1==1) {
        if(maxn1==1) {
            if(k>=1)
                puts("Beautiful flowers!");
            else 
                puts("Oh! My poor HJ!");
        } else {
            if(maxn1==2) {
                if(k>=2)
                    puts("Beautiful flowers!");
                else 
                    puts("Oh! My poor HJ!");
            } else {
                if(k>=2)
                    puts("Beautiful flowers!");
                else
                    puts("Oh! My poor HJ!");
            }
        }
    } else {
        if(min1==2) {
            if(k>=2)
                puts("Beautiful flowers!");
            else
                puts("Oh! My poor HJ!");
        } else {
            if(k>=2)
                puts("Beautiful flowers!");
            else
                puts("Oh! My poor HJ!");
        }
    }
    return 0;
}

F Incompetent Fury of a Single Dog

模拟

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n;
    scanf("%d",&n);
    set<char> p;
    string s;
    cin>>s;
    for(int i=0;i<s.length();) {
        if(!p.count(s[i])) {
            p.insert(s[i]);
            i++;
        } else
            s.erase(i,1);
    }
    cout<<s.length()<<endl;
    cout<<s;
    return 0;
}

G We are singers

模拟大法好

#include<bits/stdc++.h>
using namespace std;
map<int,string> p;
vector<int> q;
void init() {
    p[1]="do",p[2]="re",p[3]="mi",p[4]="fa",p[5]="sol",p[6]="la",p[7]="si";
}
int main() {
    init();
    int n;
    scanf("%d",&n);
    q.resize(n);
    for(int i=0;i<n;i++) {
        scanf("%d",&q[i]);
    }
    int cnt=0;
    for(int i=0;i<n;i++) {
        string s;
        cin>>s;
        if(s==p[q[i]])
            continue;
        else
            cnt++;
    }
    printf("%d\n",cnt);
    return 0;
}

H Magic necklace

紫书例题,直接暴力打表

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n,t;
    scanf("%d",&t);
        while(t--) {
            scanf("%d",&n);
            switch(n) {
                case 0:{
                    cout<<"0"<<endl;
                    break;
                }
                case 1:{
                    cout<<"1"<<endl;
                    break;
                }
                case 2:{
                    cout<<"0"<<endl;
                    break;
                }
                case 3:{
                    cout<<"0"<<endl;
                    break;
                }
                case 4:{
                    cout<<"0"<<endl;
                    break;
                }
                case 5:{
                    cout<<"1"<<endl;
                    break;
                }
                case 6:{
                    cout<<"5"<<endl;
                    break;
                }
                case 7:{
                    cout<<"33"<<endl;
                    break;
                }
                case 8:{
                    cout<<"245"<<endl;
                    break;
                }
                case 9:{
                    cout<<"2053"<<endl;
                    break;
                }
                case 10:{
                    cout<<"19137"<<endl;
                    break;
                }
                case 11:{
                    cout<<"196705"<<endl;
                    break;
                }
            }
        }
    return 0;
}

J 敢敢单单的斐波那契数列

矩阵快速幂裸题

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int M = 1e9+7;
typedef long long ll;
const int mod = 1e9+7;
int n ;
struct mat
{
    ll a[15][15];
    mat(){ //重载
        memset(a,0,sizeof(a));
    }
};
mat mul(mat x,mat y)
{
    mat res;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            for(int k=0;k<2;k++)
                res.a[i][j] = (res.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
    return res;
}
ll qpow(int p)
{
    mat bas;//基础矩阵
    mat res;//单位矩阵
    for(int i=0;i<2;i++)
        res.a[i][i] = 1;
    bas.a[0][0] = bas.a[0][1] = bas.a[1][0] = 1;
    bas.a[1][1] = 0;
    while(p)
    {
        if(1&p) 
			res = mul(res,bas);
        bas = mul(bas,bas);
        p>>=1;
    }
    return res.a[0][1];//或者res.a[1][0]
}
int main()
{
    while(cin>>n) {
    	cout<<qpow(n)<<endl; //f[n] = qpow(n)
    }
    return 0;
}

L 金牌厨师HiLin与HJGG

按照DP写法,每次求和每行前缀和和每列前缀和,然后写挂了,可惜可惜。因为这个矩阵是个方阵,不是像求取最大和那样的写法,正解应当如下:因为答案具有比较明显的单调性,很容易看出这是一道二分的题目,首先预处理二维前缀和,复杂度为O(n^2),然后二分答案,因为预处理了二维前缀和,所以每次check当前答案的复杂度为O(n^2),总体复杂度为O(n^2*logn),即可通过该题。

#include <bits/stdc++.h> 
using namespace std;
const int MaxN = 2e3 + 5;
long long a[MaxN][MaxN],k;
int n;
void inti(){
    for(int i = 1 ; i <= n ; ++i){
        for(int j = 1; j <= n ; ++j){
            a[i][j] += a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
        }
    }
}
bool check(int x){
    long long res;
    for(int i = x ; i <= n ; ++i){
        for(int j = x ; j <= n ; ++j){
            res = a[i][j] - a[i - x][j] - a[i][j - x] + a[i - x][j - x];
            if(res >= k)
                return true;
        }
    }
    return false;
}
int main(){
    scanf("%d %lld",&n,&k);
    for(int i = 1; i <= n ; ++i)
        for(int j = 1;j <= n ; ++j)
            scanf("%lld",&a[i][j]);
    inti();
    int l = 1,r = n,ans = 0; 
    while(l <= r){
        int mid = l + r >> 1;
        if(check(mid)){
            ans = mid ; 
            r = mid - 1;
        }
        else 
            l = mid + 1;
    }
    if(!ans)
        puts("I'm a Gold Chef!");
    else 
        printf("%d\n",ans);
    return 0;
}
发布了45 篇原创文章 · 获赞 1 · 访问量 6757

猜你喜欢

转载自blog.csdn.net/Ls_attack/article/details/104066476
今日推荐