zoj 3836 Circulation pipe , exgcd

Circulation pipe


Time Limit: 4 Seconds      Memory Limit: 65536 KB



Darkgy is a transport pipe master. One day, due to some strange redstone signal, an Iron pipe changed its direction and make a part of the pipe system become a circulation pipe.

The circulation pipe consists of L unit pipe numbered from 0 to L-1. Every K ticks, an item will input into pipe 0, and it will be transported in pipes with 1 unit
pipe length per tick speed from pipe 0 to pipe L-1. When it was transported into pipe L-1, its direction will reversed and will be transported from L-1 to 0. When it reached pipe 0, its direction will be reversed again.

This process will repeat until the moment when there are more than C items in one of the L pipes, C is the capacity of each pipe.

For example, if L=5, K=3, C=1.

In tick 0, the first item will input into pipe 0.

In tick 3, it will be transported into pipe 3 and the second item will input into pipe 0.

In tick 4, the first item reached pipe 4 and its direction reversed, at the same time, the second item moved into pipe 1.

In tick 6, the third item appeared in pipe 0, the first item moved into pipe 2 while the second item was in pipe 3. Though the first item and the second item crossed, but......it does
not matter XD.

In tick 7, the first item and the third item meet in pipe 1, and pipe 1 blast.

Darkgy want to know in which tick, the circulation pipe will blast.

Input

There are large amount of test cases, for each test case, there will be only one line with 3 integers 1 ≤ LKC ≤ 104 which was mentioned
in the description.

Output

For each test case, you should output only one line with an integer T which means the tick when circulation pipe was blast.

Sample Input

5 3 1
1 1 1
1 1 2
1 1 3

Sample Output

7
1
2
3


用扩展gcd求解,详见代码


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

template<class T>
inline bool scan_d(T &ret){
	char c; ret = 0;
	if(c=getchar(),c==EOF) return 0;
	while(c<'0' || c>'9') c=getchar();
	while(c>='0'&&c<='9') ret = ret*10 + (c-'0'),c=getchar();
	return 1;
}

void exgcd(int a, int b, int& d, int& x, int& y){
	if(!b) {d=a; x=1; y=0;}
	else {exgcd(b, a%b, d, y, x); y -= x*(a/b);}
}

int main(){
    int L, K, C;
    int x, y, d;
    int L2, M, T, x2;
	ll ans, tmp;
	while(true){
	    if(scan_d(L)==0) break;
        scan_d(K); scan_d(C);
		if(L==1){
			printf("%lld\n", (ll)K*C);
			continue;
		}
		L--;
		L2=L<<1;
		exgcd(K, L2, d, x, y);
		M = L2/d;
		T = L2*K/d;//最靠近的两个在同一点同向的时间差
		ans = (ll)T*C;//0和L-1点的情况只能都是同向的
		for(int i=1; i<L; ++i){//枚举中间的2..L-2的情况
			if((i*2)%d) continue; //无解,不可能在i相遇
			tmp = i;
			tmp += (ll)T*(C>>1);	//因为同向的两个之间必定还有一个反向的
			if(C&1){//为C奇数则还需要一个反向的
				x2 = x*(L-i)*2/d;
				x2 -= x2/M*M;
				if(x2<=0) x2 += M;
				x2 *= K;
				tmp += x2;
			}
			if(tmp<ans) ans = tmp;
		}
		printf("%lld\n", ans);
	}
	return 0;
}

				
时间: 2024-10-07 19:26:30

zoj 3836 Circulation pipe , exgcd的相关文章

zoj 3203 Light Bulb,三分基础题

Light Bulb Time Limit: 1 Second      Memory Limit: 32768 KB Compared to wildleopard's wealthiness, his brother mildleopard is rather poor. His house is narrow and he has only one light bulb in his house. Every night, he is wandering in his incommodio

【Luogu】P2485计算器(快速幂,exgcd和Bsgs模板)

题目链接 题目描述非常直接,要求你用快速幂解决第一问,exgcd解决第二问,bsgs解决第三问. emmmm于是现学bsgs 第二问让求最小整数解好烦啊…… 假设我们要求得方程$ax+by=c(mod p)$的最小整数解 令$d=gcd(a,b)$ 我们求得一个解$x_0,y_0$使得$ax_0+by_0=d(mod p)$ 然后$x_0*frac{c}{d}$为最小整数解. #include<cstdio> #include<cstdlib> #include<algori

Linux简单程序实例(GNU工具链,进程,线程,无名管道pipe,基于fd的文件操作,信号,scoket)

一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o test.i 编译:   不同平台使用汇编语言不同,汇编将高级语言编译成汇编语言: gcc -S test.c -o test.s 汇编:   将汇编语言翻译成二进制代码: gcc -c test.c -o test.o 链接:   包含各函数库的入口,得到可执行文件: gcc -o test test.c (2

ZOJ 2655 Water Pipe bfs 带方向状态

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2655 Water Pipe Time Limit: 5 Seconds      Memory Limit: 32768 KB Two waterworks want to connect to each other with water pipes. Just as the map shows, the waterworks sit on two corners

linux C++ 网络通信 -- Broken pipe,接收端突然断开,发送没收到,仍然发送消息,会导致进程崩溃

最近做C++ 服务器时,两个服务器之间通信时,一个是logserver , 一个是gameserver ,gameserver 定时向logserver 发心跳包(也就是 logserver 相当于server , gameserver 相当于client ),突然断开logserver ,就相当于服务器崩溃了,客户端不知道,仍旧照常发数据,但是相应的连接不存在,gameserver 就会报 Broken pipe 的错误,之后,进程也崩溃了. 当然进程崩溃,是做服务器最不愿意看到的事情,所以,

进程间通信 管道 (pipe,FiFO)

管道的运行原理 管道是一种最基本的IPC机制,由pipe函数创建 #include <unistd.h> int pipe(int _pipe[2]); 调用pipe函数时在内核中开辟一块缓冲区用于通信,它有一个读端和一个写端,通过filedes参数传出给程序两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端.管道就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]):向这个文件读写数据,其实是在读写内核缓冲区.pi

create windows service base on net.pipe ,windows 服务

1.创建一个windows服务 2.添加安装程序 3.修改 4.删除自带的Proman.CS 的MAIN函数 5.修改Services,添加ServiceModel.dll public class NotificationWindowsService : ServiceBase { public ServiceHost serviceHost = null; public NotificationWindowsService() { ServiceName = "WCFNotification

zoj 3203 Light Bulb,三分之二的基本问题

Light Bulb Time Limit: 1 Second      Memory Limit: 32768 KB Compared to wildleopard's wealthiness, his brother mildleopard is rather poor. His house is narrow and he has only one light bulb in his house. Every night, he is wandering in his incommodio

c/c++ linux 进程间通信系列3,使用socketpair,pipe

linux 进程间通信系列3,使用socketpair,pipe 1,使用socketpair,实现进程间通信,是双向的. 2,使用pipe,实现进程间通信 使用pipe关键点:fd[0]只能用于接收,fd[1]只能用于发送,是单向的. 3,使用pipe,用标准输入往里写. 疑问:在代码2里不写wait函数的话,父进程不能结束,但是在代码3里也没有写wait函数,父进程却可以结束??? 1,使用socketpair: #include <stdio.h> #include <stdlib