题目来源:https://atcoder.jp/contests/abc154/tasks
还是没有达到目标,马上cf div2了,先发写了的题,明天补题(看情况)
UPD:已更新题解 及 补题
我看半天没看懂题目什么意思,看样例才知道…
那个和那个字符串相同 哪个的数就-1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
string a,b;
int aa,bb;
cin>>a>>b>>aa>>bb;
string c;
cin>>c;
if(c==a) aa--;
if(c==b) bb--;
cout<<aa<<' '<<bb<<endl;
return 0;
}
这题更水,直接输出s的长度个x就行了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
string a,b;
cin>>a;
FOR(i,0,a.length()-1) cout<<'x';
cout<<endl;
return 0;
}
这题我比较懒,方法是对原数组去重,比较去重后的有效长度和原长度…
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n);
FOR(i,1,n) r(f[i]);
sort(f+1,f+n+1);
int nn=unique(f+1,f+n+1)-f-1;
if(n==nn) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
这题也很难看懂题目意思,看了好半天。
就是让你选m个连续的pi ,每一个pi代表一个骰子的最大点数(如果是pi=7,就是七面骰子,每个值的概率相等),问投m个骰子后 骰子点数和的期望。
假如现在取了第i个,连续的m个骰子的pi乘积为 mult ,那么这个骰子的所有情况的贡献为pi*(pi+1)/2*(mult/pi)/mult
pi*(pi+1)/2表示骰子的点数和 每个点都会用(mult/pi)次 除以总概率
发现每个点的贡献就是(pi+1)/2 嘛
那就好办了 前缀和 搞定
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
double f[N];
double sum[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n); r(m);
FOR(i,1,n){
r(f[i]);
sum[i]=sum[i-1]+(f[i]+1)/2;
}
double ans=0;
FOR(i,1,n-m+1){
ans=max(ans,sum[i+m-1]-sum[i-1]);
}
printf("%.8f\n",ans);
return 0;
}
找规律,CF要开始了,先溜了 明天在解释…
UPD:更新啦~
我是分三种情况考虑的,如果m=1,那不管几位都只能取最高位。
如果m=2,那就是一个数在最高位,一个在其他位变;
如果m=3,不就是一个最高位,两个在其他位变嘛
然后细节多注意一下就ok了~
UPD:更详细的解释一下代码
首先对于小于原长度的情况,去1-9都是自由的 不受约束,我们枚举长度:
① m=1: ans+=9;
(只能取长度的最高位)
② m=2: if(i>=2) ans+=81*(i-1);
(一个取最高位另一位取其他)
③ m=3 if(i>=3) ans+=81ll*9*(i-1)*(i-2)/2;
(一个取最高位另两位取其他)
难的是长度相等的情况: 只说m=3 ,m=3知道了 1 2 都好说
以3400056123为例吧
<1> 假如首位没取满(最高位为1或2)那后面两个数都不受约束 可以用公式解决:ans+=get*9*9*(len-1)*(len-2)/2;
<2>假如取满了(取3),我们现在循环枚举第二高位的位置(设为i)
先用flag看看会不会受约束(比如中间都是0 就代表受约束),这一位不受约束那么就可以取1-9所以的数 ans+=9*9*(len-i);
否则 进入 上面<1>类似的做法,先不去满公式ans+=gg*9*(len-i);
然后类似<2> 循环第三个不为0位 以此类推即可
三层循环枚举三个不为0位的位置
其实递归可以更简单,但是就3层没必要…
而且好像可以线性解决,我是O(n3)…
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
char s[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
scanf("%s",s+1);
int len=strlen(s+1);
r(m);
LL ans=0;
FOR(i,1,len-1){
if(m==1){
ans+=9;
}
else if(m==2){
if(i>=2) ans+=81*(i-1);
}
else if(m==3){
if(i>=3) ans+=81ll*9*(i-1)*(i-2)/2;
}
}
if(m==1) ans+=s[1]-'0';
else if(m==2){
int get=s[1]-'0'-1;
if(get>0) ans+=get*9*(len-1);
FOR(i,2,len){
bool flag=1;
FOR(j,2,i-1) if(s[j]!='0') flag=0;
if(flag){
ans+=s[i]-'0';
}
else ans+=9;
}
}
else if(m==3){
int get=s[1]-'0'-1;//这一位不满
if(get>0) ans+=get*9*9*(len-1)*(len-2)/2;
FOR(i,2,len){// two
bool flag=1;
FOR(j,2,i-1) if(s[j]!='0') flag=0;
if(flag){
int gg=s[i]-'0'-1;//这一位不满
if(gg>0) ans+=gg*9*(len-i);
if(gg>=0){
FOR(j,i+1,len){
bool ff=1;
FOR(k,i+1,j-1) if(s[k]!='0') ff=0;
if(ff){
ans+=s[j]-'0';
}
else ans+=9;
}
}
}
else{
ans+=9*9*(len-i);
}
}
}
cout<<ans<<endl;
return 0;
}
这题我只能说当时 有感觉,但是奈何上一题用时太多 这题想不过来了…
我记得以前高中的排列组合有个公式,在这里就是:
f ( r , 0 ) + f ( r , 1 ) + . . . + f ( r , c ) = f ( r + 1 , c ) f(r,0)+f(r,1)+...+f(r,c) = f(r+1,c) f(r,0)+f(r,1)+...+f(r,c)=f(r+1,c) , 有且只有左式的点可以到达右式的点。 现在定义 h h h ( r , c ) hhh(r,c) hhh(r,c) 表示 从 f ( i , j ) f(i,j) f(i,j)的和 ( 0 < = i < = r , 0 < = j < = c ) (0<=i<=r,0<=j<=c) (0<=i<=r,0<=j<=c)那么 h h h ( r , c ) = f ( r + 1 , c ) + f ( r , c ) + . . . + f ( 1 , c ) = f ( r + 1 , c ) + f ( r , c ) + . . . + f ( 0 , c ) − 1 = f ( r + 1 , c + 1 ) − 1 hhh(r,c)=f(r+1,c)+f(r,c)+...+f(1,c)=f(r+1,c)+f(r,c)+...+f(0,c)-1=f(r+1,c+1)-1 hhh(r,c)=f(r+1,c)+f(r,c)+...+f(1,c)=f(r+1,c)+f(r,c)+...+f(0,c)−1=f(r+1,c+1)−1
最后一步的转化即将r与c互换然后同理.
但是题目要我们求的不是这个,但是变一下很容易得到
a n s = h h h ( r 2 , c 2 ) + h h h ( r 1 − 1 , c 1 − 1 ) − h h h ( r 2 , c 1 − 1 ) − h h h ( r 1 − 1 , c 2 ) ans=hhh(r2,c2)+hhh(r1-1,c1-1)-hhh(r2,c1-1)-hhh(r1-1,c2) ans=hhh(r2,c2)+hhh(r1−1,c1−1)−hhh(r2,c1−1)−hhh(r1−1,c2)
这个就是组合数嘛,很好求的,注意逆元~
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
LL qpow(LL a,LL p)
{
LL res=1;
while(p){
if(p&1) res=res*a%mod;
a=a*a%mod;
p>>=1;
}
return res;
}
LL inv(LL x)
{
return qpow(x,mod-2);
}
LL hhh(LL a,LL b)
{
a++; b++;
LL res=1;
FOR(i,1,a){
res=res*(a+b-i+1)%mod;
}
FOR(i,1,a){
res=res*inv(i)%mod;
}
return (res-1+mod)%mod;
}
int main()
{
LL r1,r2,c1,c2;
rrr(r1,c1,r2); r(c2);
LL a1=hhh(r2,c2);
LL a2=hhh(r1-1,c1-1);
LL a3=hhh(r1-1,c2);
LL a4=hhh(r2,c1-1);
//cout<
cout<<(a1+a2-a3-a4+mod+mod)%mod<<endl;
return 0;
}