codechef It Is Axis Time
来源:互联网 发布:算命的为何准 知乎 编辑:程序博客网 时间:2024/06/14 08:32
Problem Description
Its axis time and the event managers are busy conducting meetings or their events. Each event manager is seating on a vertex of a table having shape of a regular polygon.
The table has n vertices where n is the number of event managers in the meeting.
Your task is to count the number of isosceles triangles formed such that each vertex of the triangle is a vertex of the table and all managers seating on these 3 vertices are of same gender.
Input
The first line contains an integer T. T testcases follow.
For each test case, there is only one line, which consists of a 01-string with length >= 2.
Number of vertices n of the regular
polygon equals length of the string.
The string represents gender of managers seating on the vertices in clockwise order. 0 represents girls and 1 represents boys.
Output
For each test case, output one line in the format Case #t: ans, where t is the case number (starting from 1), and ans is the answer.
题目大意:
给你一个正n边形,告诉你它每个顶点上的数值(0或1)。要求找出三个顶点数值相同的等腰三角形。
Constraints
Sum of all n in the input <= 10^6
Example
Input:5010001100011110101101010Output:Case 1: 0Case 2: 1Case 3: 1Case 4: 2Case 5: 3
Explanation
In case 5, indices of vertices of the three monochromatic isosceles triangles are (0,3,5), (1,3,5) and (2,4,6) (assuming indices
start from 0)
题解
这题到底该算好还是不好呢?通过画图比较的结论题,跟容斥原理有点关系……鄙人蒟蒻,仅把小人所理解的写在下面。
我的第一想法是将字符串“折叠”比较,hash每个状态,重复的不记,这种做法看着都会T……
这数据范围……而且nlogn的算法(我所知道的)好像跟没什么关系嘛……O(n)的更没有了吧……所以我向已A代码屈服了。
画图可知,不管n的奇偶性,正多边形总共有n*((n-1)/2)个等腰三角形,当然这些可能包含了等边的。易证:当n%3==0时,有n个等边三角形,每个共计数3次,所以此时要减去(n/3*2)。(这应该是容斥吧!)
接下来要删掉顶点不相同的三角形,分两种情况考虑:
1、当n为奇数时,设0顶点数位s0,1顶点数为s1。画图可知,任意两点可成为3个等腰三角形的边(不足三个的可视为三个等边三角形重合)。所以,一定要删去s0*s1*3个,若n%3==0,要再特判一些答案。话说特判为什么像我这样写,应该是这样的:一个三角形一定至少有两个点数字一样(抽屉原理)。因为一对不一样的点使一个等边三角形被多算两次,所以像我那样写可以。
2、当n为偶数时,设在偶数编号上的0顶点数位s00,在偶数编号上的1顶点数为s01,在奇数编号上的0顶点数位s10,在奇数编号上的1顶点数为s11. 两个点的编号的奇偶性对这一线段所能做出的贡献是有影响的(画图可知)。所以,分类处理要删去的点,特判处理两点刚好在最长对角线上(即两点正对,因为是偶数个点,这两点所组成的线段无法构成等腰三角形)。之后对于n%3==0的情况,像1一样处理即可。
剩下的细节看代码吧!
#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<cmath>#include<algorithm>#define ll long longusing namespace std;int T,n;char a[1000005];ll calcu(){ll ans=0;ans=(ll) n*((n-1)/2);if(n%3==0) ans-=n/3*2;return ans;}ll del(){ll ans;if(n%2==1) {int s1=0,i,s0=0; for(i=0;i<n;i++) {if(a[i]=='0') s0++; else s1++; }ans=(ll)s1*s0*3;if(n%3==0) {s1=n/3; s0=n/3*2;for(i=0;i<n;i++) {if(a[i]!=a[(i+s1)%n]) ans--; if(a[i]!=a[(i+s0)%n]) ans--; } }return ans/2; }else {int i,s00=0,s01=0,s10=0,s11=0;for(i=0;i<n;i+=2) {if(a[i]=='0') s00++; else s01++; }for(i=1;i<n;i+=2) {if(a[i]=='0') s10++; else s11++; }ans=(ll)s00*s11*2; ans+=(ll)s01*s10*2;ans+=(ll)s00*s01*4; ans+=(ll)s10*s11*4;int n1,n2;n1=n/2;for(i=0;i<n;i++) {if(a[i]!=a[(i+n1)%n]) ans--;}if(n%3==0) {int s1=n/3,s0=n/3*2;for(i=0;i<n;i++) {if(a[i]!=a[(i+s1)%n]) ans--; if(a[i]!=a[(i+s0)%n]) ans--; } }return ans/2; }}int main(){scanf("%d",&T);int k;for(k=1;k<=T;k++) {scanf("%s",a); n=strlen(a);printf("Case %d: %lld\n",k,calcu()-del()); }return 0;}
- codechef It Is Axis Time
- what time is it?
- It is a long time.
- poj1676 What time is it?
- It is time to work again
- Problem 45 What Time Is It
- Web 3.0 this time it is personal
- 有目标的过着!It Is Time
- Poj 1676 What time is it?
- poj 1676 What time is it?
- poj 1676-What time is it?
- poj 1676 What time is it?
- POJ 1676 What time is it? 笔记
- Java: Is it Ready for Prime Time? @ JDJ
- Is it time to start using high-level synthesis?
- Is it worthwhile to learn English spending so much time?
- MVC is dead, it's time to MOVE on.
- 7 Signs it is Time to Quit your Job
- 安卓使用Canvas绘制工作日程表
- windows.edb文件
- 表单嵌套问题的解决方法
- THINKPAD E431 WIFI 驱动 bcmwl-6.30.223.141 在内核 3.16下的编译
- 找出n个元素中最小的k个数(编程珠玑第二章)
- codechef It Is Axis Time
- 让Android模拟飞起来
- Swap Nodes in Pairs
- 直接插入排序(Java版)
- acdream 1427
- Redis 主从复制
- html设置行距
- php快速排序方法
- 在solaris上使用rsync(1):实现两个server之间的文件传输