2016 PSUT Coding Marathon A~G

2016 PSUT Coding Marathon A~G

A.LCS (A)

输出比输入多1
#include<bits/stdc++.h>
using namespace std;

int main()
{
int n;
cin>>n;
cout<<n+1;
return 0;
}

B.LCS (B)

给c出一个DP矩阵,以及算法(求lcs),然后根据这个矩阵让你倒过来算出两个符合条件的原先的字符串。
显然要求lcs第一个字符串起到类似参照的作用,最后决定dp矩阵的数值大小的关键在于第二个字符串和第一个字符串的匹配程度。
因此考虑在状态转移中的条件,
if A[i] = B[j] DP[i,j] := DP[i-1,j-1] + 1
else DP[i,j] := max(DP[i,j-1], DP[i-1,j])
也就是说当DP[i,j]>max(DP[i,j-1], DP[i-1,j])的时候说明是从状态1(更优)转移过来的,这个时候说明这两个地方是同一种字母。多个集合指向同一种东西,想到用并查集。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline long long read()
{
	long long kk=0,f=1;
	char cc=getchar();
	while(cc<'0'||cc>'9'){if(cc=='-')f=-1;cc=getchar();}
	while(cc>='0'&&cc<='9'){kk=(kk<<1)+(kk<<3)+cc-'0';cc=getchar();}
	return kk*f;
}
int dp[30][30];
string ss,s1;
char a[30],b[30];
int fa[60];
int find(int x)
{
	if(x==fa[x])return x;
	return fa[x]=find(fa[x]);
}
void merge(int a,int b)
{
	int aa=find(a),bb=find(b);
	fa[bb]=aa;find(b);
}
int main()
{
	int n=read(),m=read();
	for(int i=0;i<58;++i)fa[i]=i;
	for(int i=0;i<=n;++i)for(int j=0;j<=m;++j)
	{
		dp[i][j]=read();
		if(dp[i][j]>max(dp[i-1][j],dp[i][j-1]))
		{
			merge(i-1,j-1+n);
		}
    } 
	for(int i=0;i<n;++i)a[i]=find(i)+'a';
	for(int i=0;i<m;++i)
	{
		int lin=find(i+n);
		if(lin==i+n)lin=25;
		b[i]=lin+'a';
	}
	cout<<a<<endl<<b;
}

C.1D Cafeteria (A)

题意 给出每张桌子座位数和已使用的座位数,求未占用的座位数.
算法 模拟

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
	int t,a,b,s=0;
	cin>>t;
	while(t--)
	{
		cin>>a>>b;
		s=s+b-a;
	}
	cout<<s;
}

D.Cafeteria (B)

题意 有N张容量已知的桌子,对于Q组来客与离客的操作,为来客分配落座的桌子,若没有合适的桌子,输出-1.
算法 模拟
解题 用set<pair<int,int>>来储存目前剩余的桌子即可.

#include<bits/stdc++.h>
using namespace std;
 
int a[100001],n,q,nu;
string str;
set<pair<int,int> > s;
set<pair<int,int> > ::iterator it;
int main()
{
	cin>>n>>q;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		s.insert(make_pair(a[i],i));
	}
	while(q--)
	{
		cin>>str>>nu;
		if(str[0]=='i') {
			it=s.lower_bound(make_pair(nu,0));
			if(it==s.end())	cout<<"-1"<<endl;
			else
			{
				cout<<it->second<<endl;
				s.erase(it);
			}
		}
		else s.insert(make_pair(a[nu],nu));
 
	}
}

E.Accepted Passwords

输入两串字符串,第一串是真密码,第二串是输入的密码。
一样的就是yes。
对于8位密码以上的可以错一位,或者漏一位

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int f=0;
	char a[1000],b[1000];
	cin>>a>>b;
	
	if(strcmp(a,b)==0) cout<<"yes";
	else if(strlen(a)<8) cout<<"no";
	else {
		if(strlen(b)==strlen(a)){
			for(int i=0;i<strlen(b);i++)
			{
				if (a[i]!=b[i]){
					if (f) {
						cout<<"no";
						return 0;
					}
					f=1;
				}
			}
			cout<<"yes";
		}
		else 
		{
			if (strlen(a)==strlen(b)+1)
			{
				for(int i=0;i<strlen(b);i++)
				{
					if(a[i+f]!=b[i])
					if(f||a[i+1]!=b[i]){
						cout<<"no";
						return 0;
					}
					else f=1;
				}
				cout<<"yes";
			}
			else cout<<"no";
		}
	}
	return 0;
}

F.Mission in Amman (A)

题意 给出初始位置已知的N人,进行Q次操作,求每一次操作过后M个场地中没人的场地的数量.
算法 模拟

#include<bits/stdc++.h>
using namespace std;
 
int a[100001],b[100001]={0},n,m,q,s=0,x,y;
int main()
{
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		b[a[i]]++;
	}
	for(int i=1;i<=m;i++)
	if (b[i]==0) s++;
	while(q--)
	{
		cin>>x>>y;
		//cout<<a[1]<<' ';
		if(b[a[x]]==1) s++;
		if(b[y]==0) s--;
		b[a[x]]--; b[y]++; a[x]=y;
		cout<<s<<endl;
	}
	return 0;
}

G.Mission in Amman (B)

输入m个数,可以移动k次每一次可以从任意一个数里面减一其他的某个数加一
要让最后的最大值最小,求这个最大值
显然,根据k的值判断是否可行,二分答案。最理想的情况是答案是平均值(向上取整),最坏的情况就是现存的最大值。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline long long read()
{
	long long kk=0,f=1;
	char cc=getchar();
	while(cc<'0'||cc>'9'){if(cc=='-')f=-1;cc=getchar();}
	while(cc>='0'&&cc<='9'){kk=(kk<<1)+(kk<<3)+cc-'0';cc=getchar();}
	return kk*f;
}
LL n,k,a[211111],asd;
int main()
{
	n=read();k=read();LL tot=0;
	for(int i=1;i<=n;++i)
	{
		a[i]=read();tot+=a[i];
	}
	sort(a+1,a+1+n);
	LL l=ceil((float)tot/n),r=a[n];asd=r;
	while(l<=r)
	{
		LL mid=l+(r-l)/2;
		tot=0;int i=lower_bound(a+1,a+1+n,mid)-a;
		for(;i<=n;++i)if(a[i]-mid>0)tot+=a[i]-mid;
		if(tot<=k)
		{
			asd=min(asd,mid);r=mid-1;
		}
		else l=mid+1;
	}
	cout<<asd;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值