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( 时进行递归 ,遇到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]);
}