Cod sursa(job #341075)

Utilizator savimSerban Andrei Stan savim Data 17 august 2009 14:34:37
Problema Robotei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <stdio.h>

#define MAX_N 1024
#define MAX_M 667000

int n, m, X, Y, modX, modY, offsetX, offsetY;
int len;
struct element {
	int x;
	int y;
} A[MAX_N][MAX_N];
int timp[MAX_N][MAX_N], use[MAX_N][MAX_N];
int nr[MAX_N][MAX_N], lin[MAX_N], col[MAX_N];
int sol[MAX_M];


void cit() {
	freopen("robotei.in", "r", stdin);
	freopen("robotei.out", "w", stdout);

	scanf("%d %d %d %d %d %d %d %d", &n, &m, &X, &Y, &modX, &modY, &offsetX, &offsetY);
}

inline int nextX(int k) {
	return (k * k + offsetX) % modX;
}                 

inline int nextY(int k) {
	return (k * k + offsetY) % modY;
}

void build_mat() {
	for (int i = 0; i < modX; i++)
		for (int j = 0; j < modY; j++) {
			nr[i][j] = 1;
			A[i][j].x = nextX(i);
			A[i][j].y = nextY(j);
		}
}

void get_len() {
	//determin lungimea ciclului din care face parte X, Y
	int p = X, q = Y, nr = 0;
	while (nr < modX * modY + 10) {
		nr++;
    	p = nextX(p);
		q = nextY(q);

		if (p == X && q == Y) {
        	len = nr;
			break;
		}
	}
}

void bfs(int p, int q) {
	if (use[p][q]) return;
	use[p][q] = 1;

	int i = nextX(p), j = nextY(q);
	bfs(i, j);

	if (p == i && q == j) return;
	if (i == X && j == Y) timp[p][q] = 1;
	else if (timp[i][j]) timp[p][q] = timp[i][j] + 1;
}

void get_time() {
	//calculez in cat timp ajung de la o pozitie p, q la X, Y
	use[X][Y] = 1;
	for (int i = 0; i < modX; i++)
		for (int j = 0; j < modY; j++)
			if (!use[i][j])
				if (!(i == X && j == Y))				
            		bfs(i, j);
}

void work(int m) {
	//avand matricea nr[i][j] = cati robotei sunt in celula i, j la momentul 1, calculez de cate ori trece un robotel prin (X, Y)
	for (int i = 0; i < modX; i++)
		for (int j = 0; j < modY; j++) {
			if (timp[i][j] || (i == X && j == Y)) {
				if (len == 0) {
                	//X,Y nu e pe vreun ciclu
                	if (timp[i][j] <= m) sol[1] += nr[i][j];
				}
				else {
                	int add = (m - timp[i][j]) / len + 1;
					if (m < timp[i][j]) add = 0;
					sol[add] += nr[i][j];
				}
			}
			if (!timp[i][j] && !(i == X && j == Y)) sol[0] += nr[i][j];
		}
}

void add_nn() {
	for (int i = 0; i < modX; i++)
		for (int j = 0; j < modY; j++)
			nr[i][j] = 0;

	for (int i = modX; i < n; i++)
		lin[nextX(i)]++;
	for (int i = 0; i < n; i++)
		col[nextY(i)]++;

	for (int i = 0; i < modX; i++)
		for (int j = 0; j < modY; j++)
			nr[i][j] = lin[i] * col[j];

	for (int i = 0; i < n; i++)
		lin[i] = col[i] = 0;
    for (int i = 0; i < modX; i++)
        lin[nextX(i)]++;
    for (int i = modY; i < n; i++)
        col[nextY(i)]++;

    for (int i = 0; i < modX; i++)
        for (int j = 0; j < modY; j++)
            nr[i][j] += lin[i] * col[j];
}

void solve() {
	build_mat();
	get_len();	
	get_time();

	work(m);
	add_nn();
	work(m - 1);		
}

void write() {
	for (int i = 0; i <= m; i++)
		if (sol[i]) 
			printf("%d %d\n", i, sol[i]);
}

int main() {

	cit();
	solve();
	write();

	return 0;
}