Problem D: 【2019基础】炮
Memory Limit:256 MB
Time Limit:1.000 S
Judge Style:Text Compare
Creator:
Submit:26
Solved:2
Description
小 X 备完马的跳法后就接着备炮的走法,他觉得炮的走法相比马的跳法简单多了。如果有个对方的棋子与炮处于同一行或同一列,并且它们中间只隔了一个棋子,则炮可以吃到这个棋子,俗称“炮打隔子”,中间那个棋子称为炮架,炮架可以是任何一方的棋子。下图为“炮打隔子”的示意图。
于是小 X 在作业中增加了炮的吃子难度,小 X 把中国象棋中的炮的功能做了扩展,扩展到只要在一条直线上炮都能隔着一个棋子打到对方的棋子,这里的直线是指从炮所在的交叉点出发到某个对方棋子所在的交叉点为止画一条直线,如果这条直线中间经过的交叉点上恰好只有一个棋子,则炮就能吃到该对方棋子。为了方便程序处理,小 X 规定炮的位置固定在左下角即(0,0)的位置上,只需要你计算左下角位置上的炮能吃到几个对方棋子。
于是小 X 在作业中增加了炮的吃子难度,小 X 把中国象棋中的炮的功能做了扩展,扩展到只要在一条直线上炮都能隔着一个棋子打到对方的棋子,这里的直线是指从炮所在的交叉点出发到某个对方棋子所在的交叉点为止画一条直线,如果这条直线中间经过的交叉点上恰好只有一个棋子,则炮就能吃到该对方棋子。为了方便程序处理,小 X 规定炮的位置固定在左下角即(0,0)的位置上,只需要你计算左下角位置上的炮能吃到几个对方棋子。
Input
输入数据第一行为一个正整数 n,表示棋盘上除了左下角的炮之外共有 n 个棋子。
接下来共有 n 行,每行三个整数表示一个棋子的位置和敌我属性。前两个数为棋子的位置,第三个数表示该棋子与炮的关系,0 表示它与炮是同一方的,可以做炮架,但不可以被炮吃;1 表示它与炮不是同一方的,既可以做炮架,又可以被炮吃。棋子位置的表示与第三题跳马相同。
输入数据保证同一位置只有一个棋子。炮的位置在左下角即(0,0)的位置上,该处保证不会有其它棋子。
接下来共有 n 行,每行三个整数表示一个棋子的位置和敌我属性。前两个数为棋子的位置,第三个数表示该棋子与炮的关系,0 表示它与炮是同一方的,可以做炮架,但不可以被炮吃;1 表示它与炮不是同一方的,既可以做炮架,又可以被炮吃。棋子位置的表示与第三题跳马相同。
输入数据保证同一位置只有一个棋子。炮的位置在左下角即(0,0)的位置上,该处保证不会有其它棋子。
Output
输出一个整数,表示左下角位置上的炮能吃到的对方棋子的数量。
Sample Input Copy
20
1 1 0
2 6 0
2 9 0
3 1 0
3 2 0
3 9 0
4 0 1
4 1 1
4 2 1
4 3 1
4 5 0
4 6 1
5 0 1
5 8 0
6 0 1
6 2 1
6 6 1
6 9 0
7 9 1
8 9 1
Sample Output Copy
3
HINT
样例解释
样例中的棋子位置如上图所示,左下角的黑炮能吃到两个红马(分别由黑车和黑卒做炮架)和一个红仕(帅做炮架)。在左下角的炮和下方那个红马(6,2)之间连一条线,你会发现这条线只经过(3,1)这个交叉点,这个点上有个黑卒作为炮架,这条直线与棋盘上的竖线还有 4 个交点,但这些交点都不是棋盘上的交叉点,不用考虑。另外(4,6)位置的红兵和(6,9)位置的黑象也与左下角的黑炮在一条直线上,但因黑象是己方的棋子,所以不被统计进答案。还有底边上的红相也不能被吃到,因为它跟左下角的炮之间隔了两个棋子(帅和仕)。
数据范围
20%的数据所有棋子都在底线上或在左边线上,即表示位置的两个数中有一个为 0
另外 30%的数据棋盘为真实的,即每个棋子的位置(x,y)满足 0<=x<=8,0<=y<=9
另外 30%的数据,0<=x,y<=10000,棋子都是对方的
100%的数据满足:0<=x,y<=10000,n<=100000,每个棋子都在不同的位置上。
HINT
由于数据较大,这里给出了较快的读入方式 read 函数:
int read()
{
char ch=getchar();
while(ch<'0'||'9'<ch)ch=getchar();
int sum=ch-'0';
ch=getchar();
while('0'<=ch&&ch<='9')
{
sum=sum*10+ch-'0';
ch=getchar();
}
return sum;
}
例如:int x=read();//新建 int 型变量 x,等价于 cin>>x;
注意:如果使用这种输入方式,请不要和 printf 和 scanf 混用,以免发生错误。
样例中的棋子位置如上图所示,左下角的黑炮能吃到两个红马(分别由黑车和黑卒做炮架)和一个红仕(帅做炮架)。在左下角的炮和下方那个红马(6,2)之间连一条线,你会发现这条线只经过(3,1)这个交叉点,这个点上有个黑卒作为炮架,这条直线与棋盘上的竖线还有 4 个交点,但这些交点都不是棋盘上的交叉点,不用考虑。另外(4,6)位置的红兵和(6,9)位置的黑象也与左下角的黑炮在一条直线上,但因黑象是己方的棋子,所以不被统计进答案。还有底边上的红相也不能被吃到,因为它跟左下角的炮之间隔了两个棋子(帅和仕)。
数据范围
20%的数据所有棋子都在底线上或在左边线上,即表示位置的两个数中有一个为 0
另外 30%的数据棋盘为真实的,即每个棋子的位置(x,y)满足 0<=x<=8,0<=y<=9
另外 30%的数据,0<=x,y<=10000,棋子都是对方的
100%的数据满足:0<=x,y<=10000,n<=100000,每个棋子都在不同的位置上。
HINT
由于数据较大,这里给出了较快的读入方式 read 函数:
int read()
{
char ch=getchar();
while(ch<'0'||'9'<ch)ch=getchar();
int sum=ch-'0';
ch=getchar();
while('0'<=ch&&ch<='9')
{
sum=sum*10+ch-'0';
ch=getchar();
}
return sum;
}
例如:int x=read();//新建 int 型变量 x,等价于 cin>>x;
注意:如果使用这种输入方式,请不要和 printf 和 scanf 混用,以免发生错误。