牛客多校第九场补题(待完善)

I-The Crime-solving Plan of Groundhog

题目大意:给定一组由(0~9)组成的数,组成两个数使乘积最小。
解题思路:用数组储存(0~9)的个数,先从(1 ~9)选最小的作为其中一个乘数,其余的数组成所能表达的最小的数。
难点应该是大数乘法(这个也不难)。

#include<iostream>
#include<math.h>
#include<string.h>
#include <algorithm>
#include <numeric>
#include <vector> 
#include <functional>
#include <list>
#include <ctype.h>
#include<map>
#include <set>
#define M 100
#define ll long long 
using namespace std;
const int N=1e5+5;
int a[15],re[N];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		memset(a,0,sizeof(a));
		memset(re,0,sizeof(re));
		int n;
		scanf("%d",&n);
		for(int i=0;i<n;i++){
			int k;
			scanf("%d",&k);
			a[k]++;
		}
		int c1;
		for(int i=1;i<=9;i++) {
			if(a[i]!=0) {
				c1=i;
				a[i]--;
				break;
			}
		}
		for(int i=1;i<=9;i++) {
			if(a[i]!=0) {
				re[0]=i;
				a[i]--;
				break;
			}
		}
		int k=1;
		for(int i=0;i<10;i++){
			while(a[i]){
				re[k++]=i;
				a[i]--;
			}
		}
		int len=k;
		int jin=0;
		for(int i=len;i>=0;i--){
			int m=re[i];
			re[i]=(jin+m*c1)%10;
			jin=(jin+m*c1)/10;
		}
		if(jin>0) printf("%d",jin);
		for(int i=0;i<len;i++) printf("%d",re[i]);
		printf("\n");
		
		
		
	}
} 

一模一样的代码第一次提交wa了,搞得我想了好久,验证了很多数据,感觉没有问题,第二次提交才AC。

A-Groundhog and 2-Power Representation

首先要了解高精度加法与2的N次方的高精度计算(看了题解后现学的)

高精度加法:参考链接
计算2的N次方(高精度):参考链接

其次要知道怎么递归:当遇到 2( 时进行递归 ,遇到2直接加
用 lon 判断一个()是否计算完

#include<iostream>
#include<math.h>
#include<string.h>
#include <algorithm>
#include <numeric>
#include <vector> 
#include <functional>
#include <list>
#include <ctype.h>
#include<map>
#include <set>
#define M 100
#define ll long long 
using namespace std;
int ans[200],alen,b[1005],p,k;
char s[20005];

void add(int b[],int len){ 
	alen=max(alen,len);
	for(int i=1;i<=alen;i++){
		ans[i]+=b[i];
		ans[i+1]+=ans[i]/10;
		ans[i]%=10;
	}
	while(ans[alen+1]) alen++;
}
void mi(ll n){
	memset(b,0,sizeof(b));
	b[1]=1;
	int k=1;                        
	for (int i=1; i<=n; i++) {   
	    int tmp = 0;
	    for(int j=1;j<=k;j++){
		b[j] = b[j]*2 + tmp;
	    tmp = b[j] /10;
	    b[j] = b[j] % 10;
	    if(tmp!=0&&j==k) k++;
	  }
	}
	add(b,k);
}
ll ksm(ll a,ll b){
     ll ans=1;
      for(;b;b>>=1){
      if(b&1) ans=ans*a;//b&1 表示b为奇数
    a= a*a;
}
return ans;
}
ll dp(ll st,ll lon){
	ll sum=0;
	p=0;
	for(int i=st;i<k;i++){
		p=max(p,i);//p用来更新 i 每次递归都要更新一次i
		if(s[i]=='(') lon++;
		if(s[i]==')') lon--;
		if(!lon) {
			mi(sum);
			return 0;
		} 
		if(s[i]==')') return ksm(2,sum);
		if(s[i]=='2') {
			if(s[i+1]=='('){  //如果是  2(   形式则递归 
				sum+=dp(i+1,lon);
				i=p;//递归完一次就更新 i 
			}
			else sum+=2;//如果只是2 则直接相加 			
		}
	} 
}
int main()
{
	scanf("%s",s);
	k=strlen(s);
	for(int i=0;i<k;i++)
		if(s[i]=='2')
			if(s[i+1]!='('){//如果只是2 则直接相加 用高精度相加则令b[1]=2; 
			memset(b,0,sizeof(b));
			b[1]=2
			;add(b,1);
			}
			else{//如果是  2(   形式则递归 
			 dp(i+1,0);
			 i=p;//递归完一次就更新 i 
		}
	for(int i=alen;i>=1;i--)printf("%d",ans[i]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值