喵哈哈村的魔法考试 Round #2 (Div.2) 题解

喵哈哈村的魔法考试 Round #2 (Div.2) 题解

A.喵哈哈村的战争

题解:

这道题就是for一遍,统计每个村子的战斗力的和,然后统计哪个村子的战斗力和大一点就好了。

唯一的坑点,就是这道题会超过int。

不过好像,我的数据好像没有出超过int的数据= =

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
	int a,b;
	while(cin>>a>>b){
		long long sum1=0,sum2=0;
		while(a--){
			int temp;
			cin>>temp;
			sum1+=temp;
		}
		while(b--){
			int tem;
			cin>>tem;
			sum2+=tem;
		}
		if(sum1>sum2)cout<<"Win"<<endl;
		else cout<<"Lose"<<endl;
	}
}

B.喵哈哈村的种花魔法

题解:

这道题无脑一点,就是线段树的区间更新,然后单点查询就好了。

机智一点的话,就是单点更新,然后区间查询的题目,用一个前缀和去维护就好了。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
long long a[maxn],b[maxn];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    for(int i=1;i<=m;i++){
        int l,r;
        long long val;
        scanf("%d%d%lld",&l,&r,&val);
        b[l]+=val;
        b[r+1]-=val;
    }
    long long sum = 0;
    for(int i=1;i<=n;i++){
        sum+=b[i];
        a[i]+=sum;
    }
    for(int i=1;i<=n;i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

C. 喵哈哈村的排队

一个无脑的做法:对于每个人进行二分,二分之后用线段树取区间最小值或者一个其他的数据结构去维护就好了。

但实际上有其他的做法:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define MAX 200002
using namespace std;

int a[MAX],ans[MAX];
vector<int> v,num;

int main()
{
    int n;
    while(~scanf("%d",&n)){
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        v.clear();
        num.clear();
        for(int i=n-1;i>=0;i--){
            if(v.size()==0 || v.back()>=a[i]){
                v.push_back(a[i]); num.push_back(i);
                ans[i]=-1;
            }else{
                int j = (lower_bound(v.rbegin(),v.rend(),a[i]) - v.rbegin());
                j = (int)v.size() - j - 1;
                ans[i] = num[j+1] - i - 1;
            }
        }
        for(int i=0;i<n;i++){
            if(i) printf(" ");
            printf("%d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

D. 喵哈哈村的序列

将a[i]在b数组中的位置记为c[i]

求c的最长上升子序列

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#define ll long long
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int n,ans;
int v[50005],a[50005];
int best[50005];
int find(int x)
{
	int t=0,l=1,r=ans;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(best[mid]<x)l=mid+1,t=mid;
		else r=mid-1;	
	}
	return t;
}
void dp()
{
	memset(best,127/3,sizeof(best));
	best[0]=0;
	for(int i=1;i<=n;i++)
	{
		int t=find(v[i])+1;
		best[t]=min(best[t],v[i]);
		ans=max(ans,t);
	}
}
int main()
{
	//freopen("formation.in","r",stdin);
	//freopen("formation.out","w",stdout);
	n=read();
	for(int i=1;i<=n;i++)a[read()]=i;
	for(int i=1;i<=n;i++)v[i]=a[read()];
	dp();
	printf("%d",ans);
	return 0;
}

E. 喵哈哈村的数字识别

这道题本意也不想让大家AC的,只要本地做出来就行了。

如果你不会这道题,你需要学一些机器学习的技巧,很多机器学习的知识都能解决这个问题。

比如KNN

posted @ 2017-02-26 14:24  qscqesze  阅读(407)  评论(2编辑  收藏  举报