Bootstrap

P1161 开灯 - 洛谷(两种解法)

目录

前言

一、暴力解法

二、使用异或运算



前言

 题目链接:P1161 开灯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

一、暴力解法

#include <stdio.h>

int is_on[2000000] = { 0 };  // 0 表示灯是关着的,1 表示灯是开着的

int main()
{
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++)  // 进行 n 次操作
	{
		double a = 0.0;
		int t = 0;
		scanf("%lf %d", &a, &t);
		for (j = 1; j <= t; j++)
		{
			int index = (int)(a * j);  // 数组下标对应编号
			if (is_on[index])
			{
				is_on[index] = 0;
			}
			else
			{
				is_on[index] = 1;
			}
		}
	}
	// 找到开着的灯的编号
	for (i = 1; i < 2000000; i++)
	{
		if (is_on[i] == 1)
		{
			printf("%d\n", i);
			break;
		}
	}
	return 0;
}

二、使用异或运算

异或运算的性质:

  1. 任意一个变量 x 与其自身进行异或运算,结果为 0,即 x ^ x = 0

  2. 任意一个变量 x 与 0 进行异或运算,结果不变,即 x ^ 0 = x

  3. 异或运算满足结合律,即 a ^ b ^ c = (a ^ b) ^ c = a ^ (b ^ c)

  4. 异或运算满足交换律,即 a ^ b = b ^ a

#include <stdio.h>

int main()
{
	int n = 0;
	scanf("%d", &n);
	int result = 0;  // 最后开着的灯的编号
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++)  // 进行 n 次操作
	{
		double a = 0.0;
		int t = 0;
		scanf("%lf %d", &a, &t);
		for (j = 1; j <= t; j++)
		{
			int id = (int)(a * j);  // 编号
			result ^= id;
		}
	}
	printf("%d\n", result);
	return 0;
}
;