A. Robot Sequence
题意:给定一个字符串,每个字符代表向上下左右其中方向移动一个单位,找出能回到原位置的子串数目。
暴力枚举.
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
char s[222];
int a[222],b[222],n,ans;
int main()
{
scanf("%d%s",&n,s+1);
for(int i=1;i<=n;i++)
{
a[i]=a[i-1];
b[i]=b[i-1];
if(s[i]=='L')a[i]++;
if(s[i]=='R')a[i]--;
if(s[i]=='U')b[i]++;
if(s[i]=='D')b[i]--;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(a[j]-a[i-1]==0&&b[j]-b[i-1]==0)
ans++;
cout<<ans;
return 0;
}
B. Cards
题意:给定一个只包含三个颜的序列,每次刻意把两个相同的颜色消成一个或者把2个不同的颜色消成另外一个颜色,问消完后最后一个颜色可能是什么。
如果序列只有1个颜色或3个颜色,那么答案就是这些颜色,对两个颜色的特判一下,也非常简单.
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
char s[N];
int R,B,G,n;
int sum;
int main()
{
scanf("%d%s",&n,s);
for(int i=0;i<n;i++)
R+=(s[i]=='R'),
B+=(s[i]=='B'),
G+=(s[i]=='G');
sum=(R!=0)+(B!=0)+(G!=0);
if(sum==3) puts("BGR");
else if(sum==1)
{
if(R)puts("R");
if(B)puts("B");
if(G)puts("G");
}
else
{
if(R==0)
{
if(B==1)
{
if(G==1)puts("R");
else puts("BR");
}
else
{
if(G==1)puts("GR");
else puts("BGR");
}
}
else if(B==0)
{
if(G==1)
{
if(R==1)puts("B");
else puts("BG");
}
else
{
if(R==1)puts("BR");
else puts("BGR");
}
}
else if(G==0)
{
if(B==1)
{
if(R==1)puts("G");
else puts("BG");
}
else
{
if(R==1)puts("GR");
else puts("BGR");
}
}
}
return 0;
}
C. Block Towers
题意:给定n和m,找出n个2的倍数和m个三的倍数,这所有的数都不能重复,问最大值最小是多少。
做法:从小到大找出比原范围稍大的所有的2的倍数和3的倍数,因为有的数既是2的倍数又是3的倍数,所以统计一下到当前的数有多少个2的倍数(
s2
数组),多少个3的倍数(
s3
数组),然后从n+m向后枚举,找到第一个
s2[i]>=m
且
s3[i]>=n
的数即为答案。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int a[3030030],s2[3003030],s3[3030030];
int n,m,W,tot;
int main()
{
cin>>n>>m;
W=max(n,m)+min(n,m)/2+20;
int l1=1,l2=1;
while(l1<=W||l2<=W)
{
int x=l1*2,y=l2*3;
if(x<=y)
{
if(x!=a[tot])
a[++tot]=x,s2[tot]=s2[tot-1]+1,s3[tot]=s3[tot-1];
else
s2[tot]++;
l1++;
}
else
{
if(y!=a[tot])
a[++tot]=y,s3[tot]=s3[tot-1]+1,s2[tot]=s2[tot-1];
else
s3[tot]++;
l2++;
}
//cout << tot <<": "<<a[tot]<<" "<<s2[tot]<<" "<< s3[tot]<< endl;
}
for(int i=n+m;i<=tot;i++)
if(s2[i]>=n&&s3[i]>=m)
{
cout<<a[i]<<endl;
return 0;
}
return 0;
}
D. Jerry’s Protest
题意:给定一个序列,二人随机从序列中拿一个数(放回)谁的大算谁赢,比赛三局两胜,已知A与B的比赛结果为前两局A胜,第三局B胜,然后求这三局B取得数的和比A取得数的和大的概率。
做法显然是dp,求出前两局A的总和比B大
x
的概率
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int sc()
{
int i=0; char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i;
}
double F[10050],f[10050],sum,ans;
int a[2222],n,mx;
int main()
{
n=sc();
for(int i=1;i<=n;i++)a[i]=sc();
sort(a+1,a+n+1);
sum=n*(n-1)/2;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
F[a[j]-a[i]]+=(double)1/sum;
mx=a[n]-a[1];
for(int i=1;i<=mx;i++)
for(int j=1;j<=mx;j++)
f[i+j]+=F[i]*F[j];
for(int i=1;i<=mx;i++) f[i]+=f[i-1];//cout<<f[i]<<endl;
for(int i=1;i<=mx;i++)
ans+=F[i]*f[i-1];
printf("%.10lf",ans);
return 0;
}
E. Simple Skewness
题意:给定一个序列,从序列中选出一些数使得平均数减去中位数最大。
枚举中位数,发现
f(x)
是单峰函数(
x
是序列长度)然后三分序列长度找出极值,可以证明序列长度为奇数时肯定存在最优解。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int sc()
{
int i=0; char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i;
}
double mx=-1;
int R,L,mid,n;
int a[200200];
long long sum[200200];
double solve(int x,int L)
{
return (double)(sum[x]-sum[x-L-1]+sum[n]-sum[n-L])/(2*L+1);
}
void cal(int x)
{
int l=0,r=min(n-x,x-1);
while(r-l>10)
{
int lmid=l+(r-l+1)/3;
int rmid=r-(r-l+1)/3;
double ansl=solve(x,lmid);
double ansr=solve(x,rmid);
if(ansr>ansl)l=lmid;else r=rmid;
}
for(int i=l;i<=r;i++)
{
double now=solve(x,i)-a[x];
if(now>mx)
mx=now,mid=x,L=i,R=i;
}
}
int main()
{
n=sc();
for(int i=1;i<=n;i++)a[i]=sc();
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
sum[i]+=sum[i-1]+a[i];
for(int i=1;i<=n;i++)
cal(i);
printf("%d\n",2*L+1);
for(int i=1;i<=L;i++)
printf("%d %d ",a[mid-i],a[n-i+1]);
if(R!=L)printf("%d ",a[mid+1]);
printf("%d",a[mid]);
return 0;
}
F. Group Projects
题意:给定一个序列,然后给里面的数任意分组,每一组的权值为这组数中的最大值减去最小值,问所有权值之和<=k的情况下有多少种分组方案。
先排序,然后动态规划,
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
#define R 1000000007
#define ll long long
using namespace std;
int sc()
{
int i=0; char c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i;
}
int c[222];
ll a[202][1002],b[202][1002];
int n,k;
int main()
{
n=sc(),k=sc();
for(int i=1;i<=n;i++)c[i]=sc();
sort(c+1,c+n+1);
c[0]=c[1];
a[0][0]=1;
for(int i=1;i<=n;i++)
{
swap(a,b);
memset(a,0,sizeof(a));
for(int j=0;j<i;j++)
for(int l=0;l<=k;l++)
if(l+j*(c[i]-c[i-1])<=k)
{
a[j][l+j*(c[i]-c[i-1])]=(a[j][l+j*(c[i]-c[i-1])]+b[j][l])%R;
if(j)
{
a[j-1][l+j*(c[i]-c[i-1])]=(a[j-1][l+j*(c[i]-c[i-1])]+(ll)j*b[j][l]%R)%R;
a[j][l+j*(c[i]-c[i-1])]=(a[j][l+j*(c[i]-c[i-1])]+(ll)j*b[j][l])%R;
}
a[j+1][l+j*(c[i]-c[i-1])]=(a[j+1][l+j*(c[i]-c[i-1])]+b[j][l])%R;
}
}
ll ans=0;
for(int i=0;i<=k;i++)
ans=(ans+a[0][i])%R;
cout<<ans;
return 0;
}
G. Raffles
好虚..据说是线段树