蓝桥杯 矩阵翻硬币

这是第一篇,写的目的就是督促自己每天多学一点为主,要是有朋友看见了请不要吐槽我的排版尴尬。同时由于我水平有限,我的程序也有时会拿不到满分(很尴尬第一篇就只拿到90%),发现问题在哪欢迎告诉我。

这些算法在用做题之前多数是不太懂的,做每个算法题都参考了各路算法大牛的博客才学会。所以我写的内容或多或少会带有其他博主的影子,但是重点是我力图把我学习中理解上的一些难点用我自己的体会通俗的描述出来,以达到集百家之长的目的。

步入正题,来看题目。

问题描述
  小明先把硬币摆成了一个 n 行 m 列的矩阵。

  随后,小明对每一个硬币分别进行一次 Q 操作。

  对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转。

  其中i和j为任意使操作可行的正整数,行号和列号都是从1开始。

  当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上。

  小明想知道最开始有多少枚硬币是反面朝上的。于是,他向他的好朋友小M寻求帮助。

  聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。然而小明很懒,不愿意照做。于是小明希望你给出他更好的方法。帮他计算出答案。
输入格式
  输入数据包含一行,两个正整数 n m,含义见题目描述。
输出格式
  输出一个正整数,表示最开始有多少枚硬币是反面朝上的。
样例输入
2 3
样例输出
1
数据规模和约定
  对于10%的数据,n、m <= 10^3;
  对于20%的数据,n、m <= 10^7;
  对于40%的数据,n、m <= 10^15;
  对于10%的数据,n、m <= 10^1000(10的1000次方)。


涉及知识点:大数相乘,大数开平方,公约数的性质,奇偶数的性质


#include<stdio.h>
#include<string.h>
#define MAX 1010
int temp[MAX]; 
//乘法函数,结果存在save中 
int multip(int save[],int fir[],int sed[],int len_fir,int len_sed)
{
	int i,j,k,len,temp;
	for(i=len_fir-1;i>=0;i--)
	{
	   for(j=len_sed-1;j>=0;j--)
	   {
	      save[i+j+1] += fir[i]*sed[j]; 
	   }	
	}
	
	for(i=len_fir+len_sed-1 ; i>0 ; i--)
	{
		save[i-1] += save[i]/10;
		save[i] = save[i]%10;
	}	
	//判断相乘后有几位 
	i=0;
	while(save[i]==0 && i<len_fir+len_sed)
	{
		i++;
	}
	len = len_fir+len_sed-i ;

	j=i;
	for(i=0;i<len;i++)
	{
		save[i]=save[i+j];
	}
	save[len]='\0';
	return len;
}
//比较函数,如果sqr的平方大于pro返回0,否则返回1 
int compare(int pro[],int sqr[],int len,int len_s)
{
	int i;
	int flag=0;//当判断到sqr的平方大于pro时flag标记为1
	int get_len; 
	memset(temp,0,sizeof(temp));	
	get_len = multip(temp,sqr,sqr,len_s,len_s);
	//首先根据长度判断大小 
	if(get_len < len)
	{
		return 1;
	}else if(get_len > len)
	{
	
		return 0;
	}
	for(i=0;i<len;i++)
	{
		if(temp[i]<pro[i])
		{
			flag = 0;
			break;
		}else if(temp[i]>pro[i])
		{
			flag = 1;
			break;
		}
	}
	
	if(flag == 1)
	{
	//	printf("len_s=%d sqr=%d temp=%d\n",len_s,sqr[0],temp[0]);
		return 0;
	}else{
		return 1;
	}
}
int getsqrt(int len,int pro[],int sqr[])
{
	int i,int_len;
	//开平方后的位数 
	if(len%2 == 0)
    {
       int_len = len/2; 
    }else{
       int_len = (len+1)/2;
    }
   
    for(i=0;i<int_len;i++)
    {
	   while(compare(pro,sqr,len,int_len))
	   {
	   	  sqr[i]++;
	   	      
	   }
	   sqr[i]--; 
    }
    return int_len;
}

int main()
{
   char n[MAX],m[MAX];
   int int_n[MAX],int_m[MAX];
   int sqrt_n[MAX],sqrt_m[MAX];
   int lenn,lenm,len,i;
   scanf("%s %s",n,m);
   lenn = strlen(n); //行数n的位数 
   lenm = strlen(m); //列数m的位数
   
   //将字符型数字转化为int,便于后续计算 
   for(i=0;i<lenn;i++)
   {
   	  int_n[i] = n[i]-'0';
   }
   for(i=0;i<lenm;i++)
   {
   	  int_m[i] = m[i]-'0';
   }

   memset(sqrt_n,0,sizeof(int)*MAX);//初始化为0 
   memset(sqrt_m,0,sizeof(int)*MAX);
   lenn = getsqrt(lenn,int_n,sqrt_n);//计算行值开平方后所得的数,存储在sqrt_n中 
   lenm = getsqrt(lenm,int_m,sqrt_m);//计算列值开平方后所得的数,存储在sqrt_m中 
   memset(temp,0,sizeof(temp));
   len = multip(temp,sqrt_n,sqrt_m,lenn,lenm);
   
   for(i=0;i<len;i++)
   {
   	printf("%d",temp[i]);
   }
   return 0; 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ct107d单片机是一种常见的单片机类型,广泛应用于各种电子设备中。蓝桥杯是中国著名的计算机及信息技术竞赛,矩阵键盘是一种常见的输入设备。下面我将介绍ct107d单片机如何与蓝桥杯矩阵键盘配合使用。 首先,ct107d单片机具有输入输出接口,可以与外部设备进行数据交互。蓝桥杯矩阵键盘通常采用矩阵排列的按钮形式,可以通过多个引脚与单片机相连。我们需要在单片机上配置对应的引脚,使其与蓝桥杯矩阵键盘的按键相对应。 然后,我们需要编写程序来读取输入的按键信息。在ct107d单片机上,可以使用GPIO口中断来实现按键的检测功能。当按键被按下时,引脚电平发生变化,触发GPIO口中断,单片机会执行相应的中断服务程序。我们可以在中断服务程序中读取按键的状态,并根据不同按键进行不同的处理。 在程序设计过程中,我们可以利用矩阵键盘的特性,将按键映射为矩阵的行和列。通过循环扫描的方式,逐一检测矩阵中的每个按键,并根据按键的状态进行相应的操作。例如,当按键按下时,可以执行一些特定的功能,如发送数据、改变显示内容等。 总结起来,ct107d单片机与蓝桥杯矩阵键盘的配合使用,需要在单片机上配置引脚连接,编写相应的程序来读取按键信息,并根据按键状态进行相应的处理。这样,就能够实现方便的按键输入功能,在蓝桥杯竞赛及其他实际应用中发挥作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值