美团2018年CodeM大赛-复赛 A B

A

题目描述

    小美有一个由n个元素组成的序列{a 1,a 2,a 3,...,a n},她想知道其中有多少个子序列{a p1,a p2,...,a pm}(1 ≤ m ≤ n, 1 ≤ p 1 < p 2 ,..., < p m ≤ n),满足对于所有的i,j(1 ≤ i < j ≤ m), a pi pj < a pj pi成立。

输入描述:

第一行一个整数n (1≤n≤100)表示序列长度。
接下来一行n个整数{a1,a2,a3,...,an}(1≤ai≤100)表示序列。

输出描述:

输出一行表示满足条件的子序列的数目。因为答案可能很大,请输出答案mod 1,000,000,007。
示例1

输入

复制
2
1 2

输出

复制
3

说明

满足条件的子序列为{1}, {2}, {1 2}。

dp搞一搞就行了。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
int dp[105],map[105][150];
int mod=1e9+7;
double a[105];
int main()
{
	int n;cin>>n;
	memset(map,0,sizeof(map));
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		map[i][i]=1;
		for(int j=i+1;j<=n;j++)
		{
			double q=(j)*(log(a[i]));
			double w=(i)*(log(a[j]));
			if(q<w) map[i][j]=1;
		}
	}
	for(int i=1;i<=n;i++)
	{
		dp[i]=1;
		for(int j=1;j<i;j++)
		{
			if(map[j][i])
			{
				dp[i]=(dp[j]+dp[i])%mod;
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	ans=(ans+dp[i])%mod;
	cout<<ans<<endl;
	return 0;
}

B

题目描述

    点点现在有Ñ个软件包。他想设计一个软件包管理器。不可避免地,他要解决软件包之间的依赖问题。
    一开始这些软件包之间没有依赖关系。但是每次点点会添加一条依赖关系A,b,表示软件包一个依赖b当这些软件包的依赖关系没有环的时候,那么这个软件包的管理器是好的,否则就是不好的。
    环的定义如下:
    对于任意K( k≥2)个软件包{a  1 ,a  2 ,...,a  k  },若对于所有的i <k满足a  i 依赖a  i + 1 ,且a  1  = a  k 成立,则这k个软件包构成一个环。
    点点想让你回答他每次加入一条依赖关系之后这个软件包是不是好的,如果是好的那么输出1,否则输出0。同时,点点希望他在加入每一条关系之后你都能回答他,所以他会在读入中对数据进行加密。你只有回答了问题才能知道下一条依赖关系是什么

输入描述:

第一行两个正整数N,M(1≤n≤100,000,1≤m≤200,000),表示软件包的个数和操作个数。软件包的标号为1个到ñ。
接下来米行,每行两个正整数u',v',表示加密后的依赖关系,保证u'≠v'。如果上一个回答为ans,实际的依赖关系为u,v,那么u'=(u + ans )mod n + 1,v'=(v + ans)mod n + 1.一开始的ans为0。

输出描述:

输出米行,每行一个数0或1,表示加入了一条依赖关系之后的回答。
示例1

输入

复制
3 4 
2 3 
1 2 
3 2 
2 3

输出

复制
1 
1 
1 
0

说明

解密后的输入为
3 4 
1 2 
2 3 
1 3 
3 1

题解:题目的意思让在线处理,但想清楚后发现完全可以二分答案,对于有向图判环可以拓扑排序和DFS这里用到了DFS。


#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
int a1[200005];
int vis[200005];
int n,m;
vector<int> G[200005];
struct node{
	int x,y;
}a[200005];
int flag;
void dfs(int u)
{
	vis[u]=-1;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(u!=v&&vis[v]==0)
		{
			dfs(v);
		}
		if(u!=v&&vis[v]==-1)
		{
			flag=1;
		}
	}
	vis[u]=1;
	return ;
}
int check(int l)
{
	memset(vis,0,sizeof(vis));
	flag=0;		//假设无环 
	for(int i=1;i<=n;i++)G[i].clear();
	G[a[1].x-1].push_back(a[1].y-1);
	for(int i=2;i<=l;i++)
	{
		G[a1[a[i].x]].push_back(a1[a[i].y]);
	}
	for(int i=1;i<=n;i++)
	{
		if(vis[i]==0)
		dfs(i);
		if(flag==1)break;
	}
	if(flag) return 1;
	else return 0;
}
int main()
{
	int x,y;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		a1[(i+1)%n+1]=i;
	}
	for(int i=1;i<=m;i++)
	{
		cin>>a[i].x>>a[i].y;
	}
	int l=1,r=m,mid;
	while(l<r)
	{
		mid=(l+r+1)/2;
		
		if(check(mid)) r=mid-1;
		else l=mid;
	}
	int i;
	for(i=1;i<=r;i++)
		printf("1\n");
	for(;i<=m;i++)
		printf("0\n");
	return 0;
}
 
 

猜你喜欢

转载自blog.csdn.net/qq_37632935/article/details/80977813
今日推荐