1001 Road To The 3rd Building
链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1001&cid=884
题意:
T组输入,每一组给定长度为n的一组数列,对于该数列存在多组i,j满足1<=i<=j<=n,可以求得每一组a[i]~ a[j]的平均数,求这个平均数的数学期望
题解:
可以先分开讨论,设i~j包含的个数为k,那么k:1 ~n,一共存在的组数有n(n+1)/2.
k=1:a[1]+...+a[n];
k=2:a[1]+2a[2]+...+2a[n-1]+a[n];
k=3:a[1]+2a[2]+3a[3]+...+3a[n-2]+2a[n-1]+a[n];
k:...
k=n-2:a[1]+2a[2]+3a[3]+...+3a[n-2]+2a[n-1]+a[n];
k=n-1:a[1]+2a[2]+...+2a[n-1]+a[n];
k=n:a[1]+...+a[n];设右边的为ans 这就是所有组数之和了,/((n+1)n/2)就是数学期望了,因为这里有一个/k,所以需要进行一个线性预处理。
(少了一个负号)
除法取模:a/b%mod= %mod
注意:
当n%2==1的时候,中间还有一个数据k=n/2+1要计算进去
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 2e5 + 5;
const ll mod = 1e9 + 7;
ll quick_pow(ll a, ll b) {
ll ans = 1;
while (b) {
if (b & 1) ans = (ans * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return ans % mod;
}
//逆元函数 公式为 (a/b)%mod=(a*b^(mod-2))%mod
ll Inv(ll a, ll b) {
return (a * quick_pow(b%mod, mod - 2)) % mod;//b->n*(n+1)/2可能会超过mod,所以要%mod
}
ll inv[maxn], a[maxn], f[maxn];
void init() {
inv[1] = 1;
for (ll i = 2; i < maxn; i++) {
inv[i] = mod - mod / i * inv[mod % i] % mod;//使得结果为正,初始化,得到的就是1/i的逆元
}
}
int main() {
init();
ll t;
scanf("%lld", &t);
f[0] = 0;
while (t--) {
ll ans = 0, n;
scanf("%lld", &n);
for (ll i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
f[i] = (f[i - 1] + a[i] % mod) % mod;//前缀和
}
ll k = 0;
for (ll i = 1; i <= n / 2; i++) {
k = (k + f[n - i + 1] - f[i - 1] + mod) % mod;//两个一起处理,因为i-1与n-i+1的系数是一样的都为这个k
ans = (ans + k * inv[i] % mod) % mod;
ans = (ans + k * inv[n - i + 1] % mod) % mod;
}
if (n % 2 == 1) {
ans = (ans + (k + a[n / 2 + 1]) % mod * (inv[n / 2 + 1]) % mod) % mod;
}
ans = Inv(ans, n * (n + 1) / 2);
printf("%lld\n", ans % mod);
}
return 0;
}1002 Little Rabbit's Equation
链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=884
题意:
输入多个字符串,输出算式成立是在几进制下,若不存在输出-1
题解:
模拟暴力,遍历2~ 16进制,看等式是否成立
注意:
当运算为/时,必须整除才行,如7/2=3应该输出-1
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int main()
{
char x[20];
while(scanf("%s",x)!=EOF)
{
ll len=strlen(x);
char ch;int maxn=1, i,j;
for(i=0;i<len;i++)
{
if(x[i]<='9'&&x[i]>='0')maxn=max(maxn,x[i]-'0');//找出最大的数字,则进制可能在maxn+1~16里头之中
else if(x[i]<='F'&&x[i]>='A')maxn=max(maxn,x[i]-'A'+10);
if(x[i]=='+'||x[i]=='-'||x[i]=='*'||x[i]=='/')ch=x[i];
}
int flag=0;
for( i=maxn+1;i<=16;i++)
{
ll a=0,b=0,c=0,ab=-1;//i表示进制,j表示遍历
j=0;
for(j;j<len;j++)
{
if(x[j]<='9'&&x[j]>='0')a=x[j]-'0'+a*i;
else if(x[j]<='F'&&x[j]>='A')a=a*i+x[j]-'A'+10;
else break;
}
for(j+=1;j<len;j++)
{
if(x[j]<='9'&&x[j]>='0')b=x[j]-'0'+b*i;
else if(x[j]<='F'&&x[j]>='A')b=b*i+x[j]-'A'+10;
else break;
}
for(j+=1;j<len;j++)
{
if(x[j]<='9'&&x[j]>='0')c=x[j]-'0'+c*i;
else if(x[j]<='F'&&x[j]>='A')c=c*i+x[j]-'A'+10;//可以乘以1LL*将int类型的数据转成ll型输出
else break;
}
if(ch=='+')ab=a+b;
else if(ch=='-')ab=a-b;
else if(ch=='*')ab=a*b;
else {
if(a%b==0)ab=a/b;//得到的数都是整数
}
if(ab==c){flag=1;break;}
}
if(flag)printf("%d\n",i);
else printf("-1\n");
}
return 0;
}1006 A Very Easy Graph Problem(明天再补)
链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1006&cid=884
题意:
题解:
注意:
代码:
1009 Divisibility
链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1009&cid=884
题意:
T组数据,每一组数据给定一个b,x。任意的b进制的数y=若
%x==0 ,则输出T,否则输出F
题解:
y=
当b=1时,成立,同理,当b%x==1时也成立
注意:
我当时理解错了,以为是把y转换成10进制,没想到是这几个数直接加起来%x,实力坑队友
代码:
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int main()
{
int t;ll b,x;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&b,&x);
if(b%x==1)printf("T\n");
else printf("F\n");
}
return 0;
}
京公网安备 11010502036488号