zoukankan      html  css  js  c++  java
  • 计数(数学题,思维技巧)

    计数

    Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

    Description

    给定空间里n个点,其中没有三点共线。每两个点之间都用红色或蓝色线段连接。如果一个三角形的三条边同色,则称这个三角形是单色三角形。给出红色线段的列表,求出单色三角形的总数。

    Input

    第一行测试数据的总数T。

    对于每个测试数据。

    第一行为点数n(3<=n<=1000).

    第二行为红色线段的总数m(m<=250000).

    接下来m行每行两个整数u和v,表示点u和点v之间的线段为红色线段。

    Output

    输出单色三角形的总数

    Sample Input

    1
    6
    9
    1 2
    2 3
    2 5
    1 4
    1 6
    3 4
    4 5
    5 6
    3 6

    Sample Output

    2

    //这题暴力三重循环也能过。。。数据较弱

    328ms

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 int n,m;
     5 int ans;
     6 int bian[1005][1005];//0为蓝,1为红
     7 
     8 int func(int u)
     9 {
    10     int i,j;
    11     int s1,s2,s3;
    12     for (i=u+1;i<=n;i++)
    13     {
    14         if (i==u) continue;
    15         s1=bian[u][i];
    16         for (j=i+1;j<=n;j++)
    17         {
    18             if (j==u) continue;
    19             s2=bian[i][j];
    20             if (s2==s1)
    21             {
    22                 s3=bian[j][u];
    23                 if (s2==s3)
    24                 {
    25                     ans++;
    26                     //printf("%d %d %d
    ",u,i,j);
    27                 }
    28             }
    29         }
    30     }
    31 }
    32 
    33 int main()
    34 {
    35     int T;
    36     scanf("%d",&T);
    37     while (T--)
    38     {
    39         scanf("%d",&n);
    40         memset(bian,0,sizeof(bian));
    41         scanf("%d",&m);
    42         int i;
    43         int u,v;
    44         for (i=1;i<=m;i++)
    45         {
    46             scanf("%d%d",&u,&v);
    47             bian[u][v]=bian[v][u]=1;
    48         }
    49 
    50         ans=0;
    51         for (i=1;i<=n;i++)
    52         {
    53             func(i);
    54         }
    55         printf("%d
    ",ans);
    56     }
    57     return 0;
    58 }
    View Code

    //当然,必须上简便方法,方法是这样的,如果是 n 边形,看其中的一个点,如果有a个红边连着它,就有 n-1-a 的蓝边连着它。

    a * (a-1-n) 的意思便是由这个点会组成多少不同颜色的三角形,将点遍历一遍,求出有多少不同颜色的三角形,关键在去重,不是除3,而是除2

    因为要组成个三角形不但要连接每个点的两条边,还需要一个边,但是只有两种颜色,所以第三边肯定不是红就是蓝,所以每一个不同颜色的三角形被 2 个点重复计算了,所以除2

    然后用组合公式 C(n,3) 减去就是答案 

    40ms

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 int dot[1005];
     5 int n,m;
     6 
     7 int C(int a,int b)//  a!/(a-b)!/b!
     8 {
     9    return n*(n-1)*(n-2)/6;
    10 }
    11 
    12 int main()
    13 {
    14     int T;
    15     scanf("%d",&T);
    16     while (T--)
    17     {
    18         memset(dot,0,sizeof(dot));
    19         scanf("%d",&n);
    20         scanf("%d",&m);
    21         int u,v;
    22         for (int i=0;i<m;i++)
    23         {
    24             scanf("%d%d",&u,&v);
    25             dot[u]++;
    26             dot[v]++;
    27         }
    28         int Q=0;
    29         for (int i=1;i<=n;i++)
    30             Q+=(n-1-dot[i])*dot[i];
    31 
    32         int ans=C(n,3)-Q/2;
    33         printf("%d
    ",ans);
    34     }
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    switch能否作用在作用在byte、long、string上面?
    websocket(转)
    equal和hashcode、==
    List常用方法
    String,Integer,Double等类型互相转换
    BigDecimal的转换和使用
    gitHub常用命令和技巧
    SQL语句
    SpringBoot注解
    vue格式化时间
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/6047990.html
Copyright © 2011-2022 走看看