A. Sea Battle
题意:询问两个长方形的外围周长,如图中所示
注:两个长方形左侧对齐
简单题,已AC,代码如下
#include<bits/stdc++.h>
using namespace std;
int a,b,c,d;
int main()
{
scanf("%d%d%d%d",&a,&b,&c,&d);
int ans=(b+d)*2+a+c+4;
ans+=max(a+1,c+1)-min(a+1,c+1);
printf("%d",ans);
return 0;
}
B. Draw!
题意:给出比赛过程中部分出现的比分,问有几次平分的时候
注:0:0也算一次
简单题,已AC,代码如下
#include<bits/stdc++.h>
using namespace std;
const int maxn=101000;
int n,a[maxn],b[maxn];
int main()
{
scanf("%d",&n);
a[0]=0;a[1]=0;
int ans=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
if(b[i-1]>=a[i-1]&&b[i-1]<=a[i])
ans+=min(a[i],b[i])-b[i-1]+1;
else if(a[i-1]>=b[i-1]&&a[i-1]<=b[i])
ans+=min(a[i],b[i])-a[i-1]+1;
if(a[i-1]==b[i-1]&&i!=1) ans--;
}
printf("%d",ans);
return 0;
}
C. Birthday
题意:给出n个人的身高,让他们围成一圈,是相邻两人最大差值最小
题解:排序,让身高 矮------>高---------->矮
简单题,已AC,代码如下
#include<bits/stdc++.h>
using namespace std;
int n,a[110];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
int i;
for(i=1;i<=n;i+=2)
printf("%d ",a[i]);
for(i=n-n%2;i;i-=2)
printf("%d ",a[i]);
return 0;
}
D. Gourmet choice
题意:给出矩阵,i行j列表示a[i]和b[j]的关系,询问这种关系是否成立,成立则输出一种可能结果,并使得最大的数最小
题解:相等的用并查集,然后用拓扑排序从大的指向小的
已AC,代码如下
代码写的丑,敬请谅解
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2010;
struct edge{
int to,nxt;
}e[maxn*maxn/2];
int head[maxn],cnt;
int mp[maxn][maxn],vis[maxn],fa[maxn];
void add(int u,int v){
e[++cnt].to=v; e[cnt].nxt=head[u];
head[u]=cnt;
}
int pre[maxn<<1],in[maxn],dep[maxn];
queue<int>que;
int Find(int x){
return x==pre[x] ? x:pre[x]=Find(pre[x]);
}
void join(int x,int y){
int p=Find(x),q=Find(y);
if(p<q) swap(p,q);
if(p!=q) pre[p]=q;
}
int n,m;
char s[maxn][maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n+m;i++) pre[i]=i;
for(int i=1;i<=n;i++){
scanf("%s",s[i]+1);
for(int j=1;j<=m;j++){
if(s[i][j]=='=') join(i,j+n);
}
}
for(int i=1;i<=n+m;i++){
fa[i]=Find(i);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i][j]=='=') continue;
if(fa[i]==fa[j+n]){
puts("No");
return 0;
}
if(s[i][j]=='>'){
if(mp[fa[i]][fa[j+n]]) continue;
add(fa[i],fa[j+n]);
in[fa[j+n]]++;
mp[fa[i]][fa[j+n]]=1;
}
if(s[i][j]=='<'){
if(mp[fa[j+n]][fa[i]]) continue;
add(fa[j+n],fa[i]);
in[fa[i]]++;
mp[fa[j+n]][fa[i]]=1;
}
}
}
set<int>st;
for(int i=1;i<=n+m;i++){
if(in[fa[i]]==0&&i==fa[i]){
que.push(fa[i]);
dep[fa[i]]=1;
vis[fa[i]]=1;
}
st.insert(fa[i]);
}
int maxx=1,cnt=st.size();
while(que.size()){
int p=que.front();
cnt--;
que.pop();
for(int i=head[p];i;i=e[i].nxt){
int v=e[i].to;
if(--in[v]==0){
que.push(v);
dep[v]=dep[p]+1;
maxx=max(maxx,dep[v]);
}
}
}
if(cnt>0){
puts("No");
return 0;
}
puts("Yes");
for(int i=1;i<=n;i++){
printf("%d ",maxx-dep[fa[i]]+1);
} printf("\n");
for(int i=n+1;i<=n+m;i++){
printf("%d ",maxx-dep[fa[i]]+1);
} printf("\n");
return 0;
}
E. String Multiplication
题意:将后一个字符串插入前一个字符串中,询问结果串中最长的连续相同子串
注:插入方式 t+s1+t+s2+…+t+sm+t
s="abc" t= "de" "deadebdecde"
题解:动态规划 dp[i][j] 输入第i个子串后,字母j最长子串有多长
只有t串的前后缀才会累积上一个串的结果
每次循环记录三种状态 1、t是否只由一个字母组成
2、t最前面的相同字母有几个
3、t最后面的相同字母有几个
已AC,代码如下
#include<bits/stdc++.h>
using namespace std;
char s[101000];
int n,dp[101000][30];
int main()
{
scanf("%d",&n);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=26;j++)
if(dp[i-1][j]) dp[i][j]=1;//初始化
int l=1,r=1,a=0,b=0,c=0,x=0,y=0;
int m=strlen(s+1);
for(;r<=m;l=r+1,r=l)
{
int u=s[l]-'a'+1;
while(r<m&&s[l]==s[r+1]) r++;
dp[i][u]=max(dp[i][u],r-l+1);
if(l==1&&r==m) a=u;
if(l==1) {b=u;x=r-l+1;}
if(r==m) {c=u;y=r-l+1;}
}
if(a) dp[i][a]=max(dp[i][a],(dp[i-1][a]+1)*m+dp[i-1][a]);//都由一个字母组成
if(dp[i-1][b]) dp[i][b]=max(dp[i][b],1+x);//前缀字母产生的影响
if(dp[i-1][c]) dp[i][c]=max(dp[i][c],1+y);//后缀字母产生的影响
if(b==c&&dp[i-1][b]) dp[i][b]=max(dp[i][b],1+x+y);//如果前后缀字母相同,影响累加
}
int ans=0;
for(int i=1;i<=26;i++)
ans=max(ans,dp[n][i]);
printf("%d",ans);
return 0;
}
F. Asya And Kittens
题意:最开始每个数在各自的集合中,每次只能合并相邻两个集合(给出两个集合中的任意数字),n个数经过n-1次合并,在同一集合中,问原始是什么样子
题解:用并查集,两个数组pre[i],bac[i],pre[i]保存i所在集合最前面的数是什么,bac[i]保存i所在集合最后面的数是什么
注:因为需要压缩路径,所以还需用一个数组保存答案
已AC,代码如下
#include<bits/stdc++.h>
using namespace std;
int n,m,pre[151000],a,b,ans[151000],bac[151000];
int Find_pre(int x)
{
int p,a;
p=x;
while(x!=pre[x]) x=pre[x];
while(p!=x)
{
a=pre[p];
pre[p]=x;
p=a;
}
return x;
}
int Find_bac(int x)
{
int p,a;
p=x;
while(x!=bac[x]) x=bac[x];
while(p!=x)
{
a=bac[p];
bac[p]=x;
p=a;
}
return x;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) {pre[i]=i;bac[i]=i;}
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
int p=Find_pre(b);
int q=Find_bac(a);
pre[p]=q;bac[q]=p;
ans[q]=p;
}
int key=-1;
for(int i=1;i<=n;i++)
if(pre[i]==i) key=i;
for(int i=1;i<=n;i++)
{
printf("%d ",key);
key=ans[key];
}
return 0;
}