链接:戳这里
输出描述
对于每个数据,输出一个实数答案,保留6位小数。
输入样例
2
3
1 2 3
3
100 100 100
输出样例
0.500000
0.000000
思路:两个for暴力找出符合条件的个数
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int T,n; int a[1001],b[1001]; int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } int Y=n*(n-1); int X=0; for(int i=1;i<=n;i++){ int num=0; for(int j=1;j<=n;j++){ if(i==j) continue; if(a[i]>a[j]) num++; } X+=num; } double ans=(double)X*1.0/Y; printf("%.6f\n",ans); } return 0; }
输入样例
4
3 4
3 2
9 3
666666 2
输出样例
-1
2
24
110888111
Hint
第一组数据没有合法拆分方案。
第二组数据方案为3=1+2,答案为1×2=2
第三组数据方案为9=2+3+4,答案为2×3×4=24。注意9=3+3+3是不合法的拆分方案,因为其中包含了重复数字。
第四组数据方案为666666=333332+333334,答案为333332×333334=111110888888。注意要对10^9 + 7取模后输出。
思路:首先肯定的是连续的数乘积肯定最大,那么我们先判断sum(1,k)是否大于n
填充完了连续的k个数之后,处理多出的值得情况,其实这里已经很明显了,直接从后往前累加1
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int T,n; int a[1001],b[1001]; int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } int Y=n*(n-1); int X=0; for(int i=1;i<=n;i++){ int num=0; for(int j=1;j<=n;j++){ if(i==j) continue; if(a[i]>a[j]) num++; } X+=num; } double ans=(double)X*1.0/Y; printf("%.6f\n",ans); } return 0; }
思路:我们设定两个数组 val[i]和num[i] 分别代表当前节点的贡献,儿子数
计算当前的值贡献 val[i]=val[i]+val[i]*num[j]+val[j]*num[i]
这段代码的意思是在树上,当前节点的贡献值等于它的儿子的贡献乘以父亲原有的儿子+当前父亲的贡献乘以儿子的儿子数,似乎很难理解 那我就不说了
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 #define mod 1000000007 using namespace std; int T,n; struct edge{ int u,v,next; }e[2000100]; int head[200010],tot; ll val[200010],num[200010]; void init(){ mst(head,-1); tot=0; for(int i=1;i<=n;i++) val[i]=num[i]=1; } void add(int u,int v){ e[tot].u=u; e[tot].v=v; e[tot].next=head[u]; head[u]=tot++; } void DFS(int u,int fa){ for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(v==fa) continue; DFS(v,u); val[u]=(val[u]+val[u]*num[v]+val[v]*num[u])%mod; num[u]=num[u]*(num[v]+1)%mod; } } int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); init(); for(int i=2;i<=n;i++){ int x; scanf("%d",&x); add(i,x); add(x,i); } DFS(1,0); ll ans=0; for(int i=1;i<=n;i++){ ans+=val[i]; ans%=mod; } printf("%I64d\n",ans); } return 0; }