18728 数对问题二

18728 数对问题二

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC

Description

此题目与数对问题一的唯一区别为序列中元素的取值范围。
一个长度为N的正整数序列,现在需要计算出有多少对数字的差的绝对值为C。
注意只要位置不同就认为是不相同的数对。

输入格式

第一行,两个整数 N, C。(1=<N<=10000),(1=<C<=10000)
第二行,N个正整数a1…an。 ai为int范围内的正整数。

输出格式

仅一行,满足条件的数对的个数。

输入样例

4 1
1 2 3 1

输出样例

3

提示

(a1,a2),(a2,a3),(a2,a4)共3个数对满足条件。

注意,我的哈希表是一个数两个位置,第一位为数,第二位为数的个数
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "iostream"
#include "string"
using namespace std;
#include <vector>

int main(void){
	//定义一个数组
	int num[10005];
	vector <int> hash[10005];
	//次数k
	int k = 0;
	int N,C;
	int remainder;
	cin >> N >> C;
	for (int i = 1; i <= N; i++) {
		cin >> num[i];
	}
	//录入第一个
	remainder = num[1] % 9997;
	hash[remainder].push_back(num[1]);
	hash[remainder].push_back(1);
	for (int i = 2; i <= N; i++) {
		int j;
		int a = num[i] - C;
		int b = num[i] + C;

		//一定要判断a>0才能够查
		if (a > 0) {
			//查这个数有没有   如果有就+次数
			remainder = a % 9997;
			for (j = 0; j < hash[remainder].size(); j += 2) {
				if (a == hash[remainder][j]) {
					k += hash[remainder][j + 1];
					break;
				}
			}
		}

		//同理,这里因为b是num[i]+C必为正数  不用判断直接可以查
		remainder = b % 9997;
		for (j = 0; j < hash[remainder].size(); j += 2) {
			if (b == hash[remainder][j]) {
				k += hash[remainder][j + 1];
				break;
			}
		}

		//num[i]在哈希表次数+1  
		remainder = num[i] % 9997;
		//找到j的位置
		for (j = 0; j < hash[remainder].size(); j += 2) {
			if (num[i] == hash[remainder][j]) {
				hash[remainder][j + 1]++;
				break;
			}
		}

		//注意 j的位置   是 最后一个数位置+2   如果哈希表为空j为0
		//如果没出现过并且  哈希表不为空
		if (j > 0) {
			if (j == hash[remainder].size() && num[i] != hash[remainder][j - 2]) {
				hash[remainder].push_back(num[i]);
				hash[remainder].push_back(1);
			}
		}
		//如果没出现过并且  哈希表为空
		else if (j == 0) {
			hash[remainder].push_back(num[i]);
			hash[remainder].push_back(1);
		}
	}
	cout << k;
return 0;
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解答这个问题。 1. 利用定时器T0方式1输出一个200ms周期的方波 定时器T0的方式1是16位定时器,可以用于产生定时中断,也可以用于产生PWM波。我们可以使用定时中断的方式,通过改变中断服务程序中P4.6的输出状态来实现控制LED10的亮灭。 根据题目要,我们需要输出一个200ms周期的方波,时钟频率为12MHz。方波的周期为200ms,即20Hz,所以我们需要计算出定时器中断的时间间隔。定时器的计数为65536-T,其中T为每个计数周期的时间,T可以通过以下公式计算: T = 1 / (时钟频率 / 分频系数) 其中分频系数可以通过T0CON寄存器的相应位来设置,为1、2、4、8、16、32、64或者128。由于定时器T0是16位定时器,所以T的最大为65535。 为了得到200ms的周期,我们需要计算出T的。将上述公式代入可得: T = 1 / (12MHz / 分频系数) = 分频系数 / 12MHz 因此,当分频系数为128时,T的为128/12MHz=10.67us。我们需要计算出需要多少个T才能得到200ms的周期,即: 200ms / 10.67us ≈ 18728 因为定时器T0是16位定时器,所以其计数的范围是0-65535。因此,我们需要将计数初始设置为65535-18728=46807。 下面是一个基本的示例代码: ```c #include <xc.h> #define LED10_PORT P4_6 void interrupt isr() { if (TMR0IF) { TMR0IF = 0; // 清除中断标志位 // 切换LED10的状态 LED10_PORT = ~LED10_PORT; } } void main() { // 初始化定时器T0 T0CON = 0b11010111; // 16位定时器,分频系数为128,计数器为0 // 初始化LED10引脚 LED10_PORT = 0; P4 = 0b01000000; // 将P4.6设为输出 // 启用定时器T0中断 TMR0IE = 1; GIE = 1; // 主循环 while (1) { // do something } } ``` 2. 利用定时器T2输出一个周期为3ms,占空比为1:3的矩形波 定时器T2可以用于产生定时中断,也可以用于产生PWM波。我们可以使用定时中断的方式,通过改变中断服务程序中P4.6的输出状态来实现控制LED10的亮灭。 根据题目要,我们需要输出一个周期为3ms的矩形波,占空比为1:3,时钟频率为12MHz。我们可以通过计算得到定时器T2中断的时间间隔和占空比,然后在中断服务程序中根据计数来控制LED10的亮灭。 定时器T2的计时方式为16位自动重载定时器。为了得到一个周期为3ms的矩形波,我们可以将PR2寄存器的设置为: PR2 = 3ms / T 其中T依然可以通过上面的公式计算得到。我们可以选择合适的分频系数来满足这个要。 为了实现1:3的占空比,我们需要在定时器T2中断服务程序中增加一个计数变量,当计数变量小于3时,LED10保持亮,否则灭。 下面是一个基本的示例代码: ```c #include <xc.h> #define LED10_PORT P4_6 void interrupt isr() { static unsigned char count = 0; if (TMR2IF) { TMR2IF = 0; // 清除中断标志位 count++; if (count >= 3) { count = 0; LED10_PORT = 0; } else { LED10_PORT = 1; } } } void main() { // 初始化定时器T2 T2CON = 0b00000111; // 分频系数为1,计数器为0 PR2 = 0x23; // 定时器T2中断周期为3ms // 初始化LED10引脚 LED10_PORT = 0; P4 = 0b01000000; // 将P4.6设为输出 // 启用定时器T2中断 TMR2IE = 1; GIE = 1; // 主循环 while (1) { // do something } } ``` 3. 设计定时器0工作在16位自动重装状态 根据题目要,我们需要设计一个定时器0,使得LED7每400ms翻转一状态,LED8每200ms翻转一状态,LED9每100ms翻转一状态,LED10每50ms翻转一状态。我们可以将定时器0工作在16位自动重装状态,然后在中断服务程序中根据计数来实现这个功能。 定时器0的计时方式为16位自动重装定时器。我们需要将计数初始设置为65535-40000=25535,然后在中断服务程序中每计数到0时,将计数重置为65535-40000=25535,并更新LED7的状态。LED8、LED9和LED10的状态可以通过计数的变化来控制。 下面是一个基本的示例代码: ```c #include <xc.h> #define LED7_PORT P2_0 #define LED8_PORT P2_1 #define LED9_PORT P2_2 #define LED10_PORT P2_3 void interrupt isr() { static unsigned int count7 = 25535; static unsigned int count8 = 25535; static unsigned int count9 = 25535; static unsigned int count10 = 25535; if (TMR0IF) { TMR0IF = 0; // 清除中断标志位 // 更新LED7的状态 if (count7 == 0) { LED7_PORT = ~LED7_PORT; count7 = 25535; } else { count7--; } // 更新LED8的状态 if (count8 == 0) { LED8_PORT = ~LED8_PORT; count8 = 25535; } else if (count8 % 200 == 0) { LED8_PORT = ~LED8_PORT; } count8--; // 更新LED9的状态 if (count9 == 0) { LED9_PORT = ~LED9_PORT; count9 = 25535; } else if (count9 % 100 == 0) { LED9_PORT = ~LED9_PORT; } count9--; // 更新LED10的状态 if (count10 == 0) { LED10_PORT = ~LED10_PORT; count10 = 25535; } else if (count10 % 50 == 0) { LED10_PORT = ~LED10_PORT; } count10--; } } void main() { // 初始化定时器T0 T0CON = 0b11000111; // 16位自动重装定时器,分频系数为256,计数器为25535 // 初始化LED引脚 LED7_PORT = 0; LED8_PORT = 0; LED9_PORT = 0; LED10_PORT = 0; P2 = 0b00001111; // 将P2.0-P2.3设为输出 // 启用定时器T0中断 TMR0IE = 1; GIE = 1; // 主循环 while (1) { // do something } } ``` 希望这个回答能够帮助到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值