题目3 : 八卦的小冰

时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

小冰是个八卦的人,最近她对一个社交网站很感兴趣。

由于小冰是个机器人,所以当然可以很快地弄清楚这个社交网站中用户的信息啦。

她发现这个社交网站中有N个用户,用户和用户之间可以进行互动。小冰根据用户之间互动的次数和内容判断每对用户之间的亲密度。亲密度非负,若大于零表示这两个用户之间是好友关系。由于这个网站是活跃的,所以小冰会不停地更新用户之间的亲密度。

由于隐私保护,小冰无法知道每个用户的确切性别,但是作为一只很聪明的人工智能,小冰可以通过每个用户的行为来猜测性别。当然这种猜测是不准确的,小冰有可能会改变对一个用户的判断。

小冰想知道这个社交网络的八卦度是多少。八卦度的定义是社交网络中所有异性好友之间的亲密度之和。你能帮助她吗?

输入

第一行一个整数T,表示数据组数。接下来是T组数据,每组数据的格式如下:

第一行是三个整数N, M, Q,分别表示用户数、初始的好友对数、操作数。

第二行是N个空格隔开的数,第i个数表示i号用户的性别,用0或1表示。

接下来的M行,每行三个数x, y, z,代表初始状态用户x和用户y之间的亲密度是z。除此之外的用户之间的亲密度初始为0。

接下来是Q行,每行是以下三种操作中的一种:

1. “1 x”:改变用户x的性别

2. “2 x y z”:改变用户x与用户y之间的亲密度为z

3. “3”:询问八卦度

输出

对于每组数据首先输出一行"Case #X:",X为测试数据编号。

接下来对于每一个询问,输出一行包含询问的八卦度。

数据范围

1 ≤ T ≤ 20

1 ≤ x, y ≤ N

0 ≤ z ≤ 100000

小数据

1 ≤ N, M ≤ 100

1 ≤ Q ≤ 1000

大数据

1 ≤ N, M, Q ≤ 100000

样例输入
1
3 2 8
0 1 0
1 2 1
1 3 1
3
1 1
1 2
3
2 2 3 2
3
1 2
3
样例输出
Case #1:
1
2
2
3

EmacsNormalVim
题意:构建无向图,成员编号是1~N,每个成员当作一个点,而且每个成员有分男女性别,在这无向图中,每一条边表示两个成员之间的亲密度,询问异性之间亲密度的总和。一开始让如每一个成员的性别用 0 1表示,在输入初始化的无向图。输入操作数1 x,表示改变x编号成员的性别,输入操作数2 x y z,表示改变编号x和编号y的亲密度为z,输入操作数3 ,询问异性之间亲密度的总和,在于题目的大数据点和边都比较大,用临街矩阵做不了,需要采用的是用邻接表来实现记录无向图。
题目的难点在于对于每一次的询问,如果都要进行查找,则会超时。
1,所以,用sum来记录异性亲密度总和,在初始的无向图时,判断下性别,累加异性的亲密度。
2,在修改性别也同样更新sum,因为改变性别的,结果只是会影响到与该点所连接的亲密度是否需要累加,
a,如果修改后性别一样,说明之前性别不一样,也就是之前就有加过这个顶点的权值了,而且,现在性别一样,所以sum需要减去这顶点的的权值来实现更新;
b,如果修改后性别不一样,说明之前的性别一样,也就是之前没有加上该顶点的权值,现在性别不一样,所以,sum直接加上当前顶点的权值来实现更新;
3,如果修改的是两个成员的关系,则有可能是添加新的边或者是修改已经有的点的权值。如果是修改已有边的权值需要你去查找改变,并且更新sum,如果是新建边,则只需要继续累加sum即可;
4,题目中的边数量可能会比较大,在操作的时候,可能一直添加边,提交结果有时候确实TLE而不是RE,囧囧囧。。。
PS:链表的边数=无向图边数*2,这个忘记了导致出错,判断居然还是提示TLE而不是RE,囧囧囧囧。。。
一下代码使用两种方法记录答案,一个是按照边数记录,一个是按照链表的边数记录;

  1 /*记录无向图的边数*/
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #define MAX 100010
  6 using namespace std;
  7 int SEX[100010];    //性别
  8 typedef struct edge
  9 {
 10     int TO;     //下一个顶点
 11     int Next;   //记录下一条边的编号
 12     int Vlaue;  //权值
 13 }EDGE;
 14 EDGE ID[3*MAX];   //边表,坑爹的边数,记得弄多点,不然有时候也会提示超时。
 15 int First[MAX]; //First[x]:x表示头结点为x,First[x]表示下一条边的编号
 16 int SIGN;
 17 long long sum;
 18 void Add_E(int x,int y,int z)   //添加边
 19 {
 20     ID[SIGN].TO=y;
 21     ID[SIGN].Vlaue=z;
 22     ID[SIGN].Next=First[x];
 23     First[x]=SIGN++;
 24 }
 25
 26 void C_SEX()
 27 {
 28     int n,i;
 29     scanf("%d",&n);
 30     SEX[n]=1-SEX[n];        //改变性别
 31     for(i=First[n];i!=0;i=ID[i].Next)   //查找与该点相关的点
 32     {
 33         if(SEX[ID[i].TO]==SEX[n])    //与修改后的性别一样,
 34         {                            //说明之前是加上该点的权值,
 35             sum-=ID[i].Vlaue;      //减去该点的权值
 36         }
 37         else
 38         {                            //与修改后的性别不一样
 39             sum+=ID[i].Vlaue;      //说明之前是没有加上该点的权值,
 40         }                            //现在就加上该点的权值
 41     }
 42     return ;
 43 }
 44 void C_Map()
 45 {
 46     int x, y, z,i,Begin=0;
 47     scanf("%d %d %d",&x,&y,&z);
 48     for(i=First[x];i!=0;i=ID[i].Next)//查找是否已经存在的关系
 49     {
 50         if(ID[i].TO==y)//存在关系
 51         {
 52             Begin=ID[i].Vlaue;
 53             ID[i].Vlaue=z;
 54             break;
 55         }
 56     }
 57     if(i!=0)
 58     {
 59         for(i=First[y];i!=0;i=ID[i].Next)//查找是否已经存在的关系
 60         {
 61             if(ID[i].TO==x)//存在关系
 62             {
 63                 ID[i].Vlaue=z;
 64                 break;
 65             }
 66         }
 67     }
 68     else if(i==0)//如果没有存在关系,创建两个点
 69     {
 70         Add_E(x,y,z);
 71         Add_E(y,x,z);
 72     }
 73     if(SEX[x]!=SEX[y])//如果性别不一样,减去之前权值,加上当前的权值
 74         sum+=(z-Begin);
 75
 76     return ;
 77 }
 78
 79 void FIND()//输出答案
 80 {
 81     printf("%lld\n",sum);
 82     return ;
 83 }
 84 void work()
 85 {
 86     int N;
 87     scanf("%d",&N);
 88     switch(N)
 89     {
 90         case 1:C_SEX();break;
 91         case 2:C_Map();break;
 92         case 3:FIND();break;
 93     }
 94     return ;
 95 }
 96 int main()
 97 {
 98    int T,i,t;
 99    int N,M,Q;
100    int x,y,z;
101    scanf("%d",&T);
102    t=1;
103    while(T--)
104    {
105         scanf("%d %d %d",&N,&M,&Q);
106         SIGN=1;sum=0;
107         for(i=1;i<=N;i++)
108         {
109             scanf("%d",&SEX[i]);
110             First[i]=0;
111         }
112         for(i=1;i<=M;i++)
113         {
114             scanf("%d %d %d",&x,&y,&z);
115             Add_E(x,y,z);
116             Add_E(y,x,z);
117             if(SEX[x]!=SEX[y])sum+=z;   //判断性别不一样相加
118         }
119         printf("Case #%d:\n",t++);
120         while(Q--)
121         {
122             work();
123         }
124    }
125    return 0;
126 }

View Code

  1 /*按照链表的边数记录*/
  2 #include <iostream>
  3 #include <stdio.h>
  4 #include <string.h>
  5 #define MAX 100010
  6 using namespace std;
  7 int Len;            //人数
  8 int SEX[100010];    //性别
  9 typedef struct edge
 10 {
 11     int TO;     //下一个顶点
 12     int Next;   //记录下一条边的编号
 13     int Vlaue;  //权值
 14 }EDGE;
 15 EDGE ID[3*MAX];   //边表,坑爹的边数记得多弄些,不然有可能会TLE
 16 int First[MAX]; //First[x]:x表示头结点为x,First[x]表示下一条边的编号
 17 int SIGN;
 18 long long sum;
 19 void Add_E(int x,int y,int z)   //添加边
 20 {
 21     if(SEX[x]!=SEX[y])sum+=z;   //判断性别不一样相加
 22     ID[SIGN].TO=y;
 23     ID[SIGN].Vlaue=z;
 24     ID[SIGN].Next=First[x];
 25     First[x]=SIGN++;
 26 }
 27
 28 void C_SEX()
 29 {
 30     int n,i;
 31     scanf("%d",&n);
 32     SEX[n]=1-SEX[n];        //改变性别
 33     for(i=First[n];i!=0;i=ID[i].Next)   //查找与该点相关的点
 34     {
 35         if(SEX[ID[i].TO]==SEX[n])    //与修改后的性别一样,
 36         {                            //说明之前是加上该点的权值,
 37             sum-=ID[i].Vlaue*2;      //减去该点的权值(无向图)
 38         }
 39         else
 40         {                            //与修改后的性别不一样
 41             sum+=ID[i].Vlaue*2;      //说明之前是没有加上该点的权值,
 42         }                            //现在就加上该点的权值(无向图)
 43
 44     }
 45 }
 46 void C_Map()
 47 {
 48     int x, y, z,i;
 49     scanf("%d %d %d",&x,&y,&z);
 50     for(i=First[x];i!=0;i=ID[i].Next)//查找是否已经存在的关系
 51     {
 52         if(ID[i].TO==y)//存在关系
 53         {
 54             if(SEX[x]!=SEX[y])//如果性别不一样,减去之前权值,加上当前的权值
 55                 sum+=(z-ID[i].Vlaue);
 56             ID[i].Vlaue=z;
 57             break;
 58         }
 59     }
 60     if(i!=0)
 61     {
 62         for(i=First[y];i!=0;i=ID[i].Next)//查找是否已经存在的关系
 63         {
 64             if(ID[i].TO==x)//存在关系
 65             {
 66                 if(SEX[x]!=SEX[y])//如果性别不一样,减去之前权值,加上当前的权值
 67                     sum+=(z-ID[i].Vlaue);
 68                 ID[i].Vlaue=z;
 69                 break;
 70             }
 71         }
 72     }
 73     else if(i==0)//如果没有存在关系,创建两个点
 74     {
 75         Add_E(x,y,z);
 76         Add_E(y,x,z);
 77     }
 78
 79 }
 80
 81 void FIND()//输出答案
 82 {
 83     printf("%lld\n",sum/2);//无向图,所以/2;
 84 }
 85 void work()
 86 {
 87     int N;
 88     scanf("%d",&N);
 89     switch(N)
 90     {
 91         case 1:C_SEX();break;
 92         case 2:C_Map();break;
 93         case 3:FIND();break;
 94     }
 95 }
 96 int main()
 97 {
 98    int T,i,t;
 99    int N,M,Q;
100    int x,y,z;
101    scanf("%d",&T);
102    t=1;
103    while(T--)
104    {
105         scanf("%d %d %d",&N,&M,&Q);
106         Len=N;SIGN=1;sum=0;
107         for(i=1;i<=N;i++)
108         {
109             scanf("%d",&SEX[i]);
110             First[i]=0;
111         }
112         for(i=1;i<=M;i++)
113         {
114             scanf("%d %d %d",&x,&y,&z);
115             Add_E(x,y,z);
116             Add_E(y,x,z);
117         }
118         printf("Case #%d:\n",t++);
119         for(i=0;i<Q;i++)
120         {
121             work();
122         }
123    }
124    return 0;
125 }

View Code

转载于:https://www.cnblogs.com/Wurq/p/4463080.html

2015 编程之美 八卦的小冰相关推荐

  1. 2015编程之美资格赛 回文子序列个数

    时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a& ...

  2. python画八卦_python编程也能八卦?

    python编程也能八卦?是的,而且能让八卦的逼格瞬间提升,今天python培训班就以运动员美好身材鉴赏指南为例,为你解读如何用python编程正经地八卦. 如果有10个人关注"体育赛事&q ...

  3. 《编程之美》读书笔记19: 3.9 重建二叉树

    <编程之美>读书笔记19: 3.9 重建二叉树 对根节点a以及先序遍历次序P和中序遍历次序I,查找a在I中的位置,将I分为两部分,左边部分的元素都在a的左子树上,右边的元素都在a的右子树上 ...

  4. Code Rally 2015 编程锦标赛启动,智能手表,iPad 大奖等你来拿!

    Code Rally 2015 编程锦标赛是由 IBM 和 InfoQ 主办的年度系列活动.Code Rally 2015 是一场以免费与开源为特色的竞速游戏--与传统意义上的赛道竞速不同,在这里,参 ...

  5. 编程之美计算0到N中包含数字1的个数

    转自:http://blog.csdn.net/hongjuntu123/article/details/8743266 有这样一个函数f(n),对于任意正整数n,它表示从 0 到 n 之间出现&qu ...

  6. 《编程之美》读书笔记08:2.9 Fibonacci序列

    <编程之美>读书笔记08:2.9 Fibonacci序列 计算Fibonacci序列最直接的方法就是利用递推公式 F(n+2)=F(n+1)+F(n).而用通项公式来求解是错误的,用浮点数 ...

  7. [搜索]字符串的相似度问题-从编程之美说起

    在<编程之美>之3.3讲到了计算字符串的相似度,请看下图 原文作者做了很详细的解释,有兴趣的朋友可以参考原文. 其实,总结为一点,是求两个字符的编辑距离,关于编辑距离,可以参考这儿 htt ...

  8. 编程之美系列之一——阶乘的运算

    前言:       本人一直以来都对算法很有兴趣,前些日子拿到<编程之美>这本书,爱不释手,遂有意将书中的一些本人觉得较有意思的题目以及自己的心得拿出来与大家分享,共同讨论,共同进步. 需 ...

  9. java并发编程之美-阅读记录1

    1.1什么是线程? 在理解线程之前先要明白什么是进程,因为线程是进程中的一个实体.(线程是不会独立存在的) 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程中的 ...

最新文章

  1. python入门必备10个坑_适合 Python 初学者的一些技巧和坑
  2. matlab丢失icuuc54,icuuc56.dll下载|
  3. tip use view.isineditmode() in your custom views to skip code when shown in eclipse
  4. Python线程join和setDaemon
  5. matlab-游标及查询
  6. 记一次.net core 集成vue 实践
  7. 基于Nokia S60的游戏开发之二
  8. 鸿蒙系统适配的电脑,鸿蒙来了!华为正式发布操作系统 适配手机电脑多类型设备...
  9. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)BIJ,签到抽奖
  10. P4692 [Ynoi2016]谁的梦
  11. Linux内核模块编程
  12. 思科模拟器的远程连接交换机的实现
  13. 计算机组装拆卸 心得,学习组装电脑的心得体会怎么写?
  14. 推荐几个不错第 Java 学习网站
  15. vue处理PDF文档流数据并实现PDF的预览以及打印功能以及处理PDF打印乱码问题
  16. 异构计算-1-10x10:一种异质性和提高能量效率的通用架构方法
  17. Android模拟器编程,Android模拟器入门[转]
  18. CEPH篇 块存储、文件存储和对象存储意义和差异及ubuntu20.4下 ceph安装
  19. Warring 不建议使用从字符串到‘char *’的转换
  20. [软件补丁]VS6 sp6补丁下载

热门文章

  1. 华为荣耀畅玩7c计算机在那,华为荣耀畅玩7C
  2. php7的foreach遍历数组,PHP中使用foreach遍历三维数组
  3. Andriod anim translate中的属性介绍
  4. 009_Spring Data JPA一对一关系
  5. 025_JavaScript数组方法
  6. 063_object标签
  7. python编程300例_经典编程100例——python版(例75)
  8. python单元测试框架-Python unittest单元测试框架总结
  9. java的23设计模式
  10. 底部导航栏Bottom navigation规范指南