您的位置:首页 > 其它

第五届ACM校赛

2016-05-09 16:12 183 查看
Problem A: M1crosoft Exce1

直接的模拟题,代码:
#include<bits/stdc++.h>
using namespace std;

struct stu
{
string text;
int align;
struct stu *f;

} p[30][30],*self;
int main()
{
//freopen("in.txt", "r", stdin);
int t,n,m,d,k,i,j,flag,b,y;
char s[10],ch[300];
char a,x;
cin>>t;
while(t--)
{
for(i=0; i<30; i++)
{
for(j=0; j<30; j++)
{
p[i][j].text="";

p[i][j].f=&p[i][j];
p[i][j].align=0;

}
}
cin>>n>>m>>d>>k;
while(k--)
{
scanf("%s",s);
getchar();
if(strcmp(s,"text")==0)
{
scanf("%c%d ",&a,&b);
fgets(ch,300,stdin);
ch[strlen(ch)-1]='\0';
p[a-'A'+1].text=ch;
}
else if(strcmp(s,"align")==0)
{
scanf("%c%d%s",&a,&b,ch);
if(strcmp(ch,"left")==0)
{
p[a-'A'+1][b].align=0;
}
else if(strcmp(ch,"right")==0)
{
p[a-'A'+1][b].align=1;
}
}
else if(strcmp(s,"merge")==0)
{
scanf("%c%d %c%d",&a,&b,&x,&y);
for(i=a; i<=x; i++)
{
for(j=b; j<=y; j++)
{
p[i-'A'+1][j].f=&p[x-'A'+1][y];
}
}
}
}
for(i=-m-1; i<m*d; i++)
{
cout<<"-";
}
cout<<endl;

for(i=1; i<=n;)
{
flag=0;
cout<<"|";
for(j=1; j<=m; j++)
{
self=p[i][j].f;
if(self->text.length()<d)
{
if(self->align==1)
{
for(k=d-self->text.length(); k>0; k--)
{
cout<<" ";
}
cout<<self->text;
}
else if(self->align==0)
{
cout<<self->text;

for(k=d-self->text.length(); k>0; k--)
{
cout<<" ";
}
}
self->text="";
}
else
{
if(self==&p[i][j])
{
flag=1;
}
cout<<self->text.substr(0,d);
self->text=self->text.substr(d);
}
if(j==m||p[i][j].f!=p[i][j+1].f)
{
cout<<"|";
}
else
{
if(self->text.length()==0)
{
cout<<" ";
}
else
{
cout<<self->text.substr(0,1);
self->text=self->text.substr(1);
}
}
}
cout<<endl;
if(flag==0)
{
cout<<"-";
for(j=1; j<=m; j++)
{
if(i==n||p[i][j].f!=p[i+1][j].f)
{
for(k=0; k<d; k++)
{
cout<<"-";
}
}
else
{
self=p[i][j].f;
if(self->text.length()<d)
{
if(self->align==1)
{
for(k=d-self->text.length(); k>0; k--)
{
cout<<" ";
}
cout<<self->text;
}
else if(self->align==0)
{
cout<<self->text;
for(k=d-self->text.length(); k>0; k--)
{
cout<<" ";
}
}
self->text="";
}
else
{
cout<<self->text.substr(0,d);
self->text=self->text.substr(d);
}
}
if(i==n||p[i][j].f!=p[i+1][j].f||p[i][j].f!=p[i][j+1].f)
{
cout<<"-";
}
else
{
self=p[i][j].f;
if(self->text.length()==0)
{
cout<<" ";
}
else
{
cout<<self->text.substr(0,1);
self->text=self->text.substr(1);
}
}
}
cout<<endl;
i++;
}
}
cout<<endl;
}
return 0;
}


[b]Problem B: J VS B


题解:简单的博弈题,考虑k>1时一定是yes;k=1时判断n的奇偶

代码:

#include<bits/stdc++.h>
using namespace std;

int main()
{
//freopen("test01.in","r",stdin);
//freopen("test01.out","w",stdout);
int n,k;
int T;
while(scanf("%d",&T)!=EOF){
while(T--){
scanf("%d%d",&n,&k);
if(k>1)
printf("yes\n");
else{
if(n%2==0)
printf("no\n");
else
printf("yes\n");
}
}
}
return 0;
}


Problem C: Jinixin Speech
题解:给你n个数,m次询问,每次询问是这样的:
输入 x,将会构造出一个新的序列,这个新的序列b[i]=a[x]-a[i](iSum2输出Keep dis
如果sum1=sum2输出Next time
如果Sum1j的时候
Sum2+=a[x][j]*(j-s[x]) (s[x]<j的时候)

然后扫一遍10个数就好了~

代码:

#include<bits/stdc++.h>

using namespace std;

long long a[100005][11];
int main()
{
long long i,j,n,m,x,tmp,A,B;
string s;
while(~scanf("%lld%lld",&n,&m))
{
memset(a,0,sizeof(a));
cin>>s;
for(i=0;i<s.size();i++)
{
if(i!=0)
for(j=0;j<10;j++)
a[i][j]=a[i-1][j];
a[i][s[i]-'0']++;
}
while(m--)
{
scanf("%lld",&x);
tmp=s[x-1]-'0';
A=B=0;
for(i=0;i<10;i++)
{
if(i<tmp)
A+=(tmp-i)*a[x-1][i];
else if(i>tmp)
B+=(i-tmp)*a[x-1][i];
}
if(A==B)
printf("Next time\n");
else if(A>B)
printf("Keep some distance from me\n");
else
printf("I agree\n");
}
}
return 0;
}


Problem D: Group Sum

题解:

题意:

给定一个数M,从1~9这9个数中选出M个不同的数,组成一个集合。

当集合中所有元素之和等于N时,输出该集合,要求找到所有满足条件的集合。

注:集合之间从小到大排序,集合内元素也要从小到大排序。

想法:

拿到题,因为集合中的元素来自1~9,且要求有序输出,所以很容易想到用循环嵌套来做,但因为题中M不确定,故用M个循环解决本题可能比较麻烦。循环与递归在某种程度上是可以相互转换的,故我们通过递归来思考本题。

vector<int> minums;
void dfs(int i,int m)
{
if(m==(int)minums.size())
{
//找到了一个长度为m的集合
return;
}
for(i++;i<=9;i++)
{
minums.push_back(i);//将i加入minums集合末尾
dfs(i,m);
minums.pop_back();//将minums集合末尾的元素删除
}
}
调用:dfs(0,m);

通过上述代码可以找到所有长度为m的集合。
minums集合中的元素满足从小到大的顺序,且找到的长度为m的集合的先后顺序也满足从小到大。
下面我们只要着手判断该集合内所有元素之和是否等于n?如果等于n则把该集合再存储进一个大集合即可。


vector<int> minums;
vector<vector<int>> nums;//大集合
void dfs(int i,int m,int n)
{
if(n<0)//集合中元素之和已经超过n
{
return;//返回
}
if(m==(int)minums.size())//找到了一个长度为m的集合
{
if(n==0)//如果集合中所有元素之和等于n,则该集合minums符合要求
{
nums.push_back(minums);//将minums存储到集合nums中
}
return;//返回
}
for(i++;i<=9;i++)
{
minums.push_back(i);//将i加入minums集合末尾
dfs(i,m,n-i);
minums.pop_back();//将minums集合末尾的元素删除
}
}
调用:dfs(0,m,n);

nums集合即为最终答案。


代码:

#include<iostream>
#include<vector>
using namespace std;
vector<int> minums;
vector<vector<int>> nums;
void dfs(int i,int k,int n)
{
if(n<0)
{
return;
}
if(k==(int)minums.size())
{
if(n==0)
{
nums.push_back(minums);
}
return;
}
for(i++;i<=9;i++)
{
minums.push_back(i);
dfs(i,k,n-i);
minums.pop_back();
}
}
int main()
{
int k,n,i,j;
while(~scanf("%d%d",&k,&n))
{
nums.clear();
minums.clear();
dfs(0,k,n);
cout<<"[";
for(i=0;i<(int)nums.size();i++)
{
cout<<"[";
for(j=0;j<k;j++)
{
printf(j==k-1?"%d":"%d,",nums[i][j]);
}
cout<<"]";
if(i!=(int)nums.size()-1)
{
cout<<",";
}
}
cout<<"]"<<endl;
}
return 0;
}


Problem E: Binary Tree
题意:

按层序给你一棵二叉树各节点值的序列(空节点值为null),要求建立该二叉树,并判断该二叉树是否具有对称性。

如果具有对称性,输出1。

如果不具有对称性,输出0,并输出该二叉树的先序遍历序列。

想法:

本题是模拟题,涉及“字符串处理”,“二叉树建树”,“先序遍历”。

注1:给定的序列是“A B C D ”这样的形式,字母表示节点的值,节点值后面一定有一个空格。

注2:题中说明“节点值为整数”,但大家需要考虑到负整数的情况!

****************************************************************************************************
//数据结构定义
struct TreeNode {
int val;
TreeNode *left,*right;
};
****************************************************************************************************
//将读入的序列转换为二叉树
TreeNode* deserialize(string data)
{
TreeNode *root,*head,*pre;
queue<TreeNode *> p;
int i=0,j=0,flag=1;//flag为0表示节点为空;为1表示正数;为-1表示负数。
//由于需要知道所建树的根节点地址,故单独先读第一个数!
while(data[i]!=' '&&i<data.size())//一直向下遍历,直到遇到空格或字符串结束
{
if(data[i]=='n')//读到“n”,跳过“null ”
{
i+=4;//这里不是3是因为null后跟一空格
flag=0;
break;//该节点为空,直接跳出
}
else if(data[i]=='-')//读到“-”,后面所跟数是负的!
{
flag=-1;//标记为负的!
i++;
}
j=j*10+data[i++]-'0';//将字符串变为数字
}
if(!flag)//当读到null时,树的根节点不存在
{
return NULL;
}
else
{
head=(TreeNode *)malloc(sizeof(TreeNode));
head->val=j*flag;//flag表示正负!
head->left=head->right=NULL;
p.push(head);//压入队列
}
while(!p.empty())
{
pre=p.front();//从队列中读出一个节点作为根节点
p.pop();
j=0;flag=1;i++;
while(data[i]!=' '&&i<data.size())//读入第一个数,具体过程同“上方代码”
{
if(data[i]=='n')
{
i+=4;
flag=0;
break;
}
else if(data[i]=='-')
{
flag=-1;
i++;
}
j=j*10+data[i++]-'0';
}
if(!flag&&i<data.size())//当读到null时,该节点不存在。即根节点的左子树不存在
{
pre->left=NULL;
}
else if(i<data.size())
{
root=(TreeNode *)malloc(sizeof(TreeNode));
root->val=j*flag;
root->left=root->right=NULL;
pre->left=root;//根的左孩子即为该数所在节点
p.push(root);//将该数所在节点压入队列
}
j=0;flag=1;i++;
while(data[i]!=' '&&i<data.size())//读入第二个数,具体过程同“上方代码”
{
if(data[i]=='n')
{
i+=4;
flag=0;
break;
}
else if(data[i]=='-')
{
flag=-1;
i++;
}
j=j*10+data[i++]-'0';
}
if(!flag&&i<data.size())//当读到null时,该节点不存在。即根节点的右子树不存在
{
pre->right=NULL;
}
else if(i<data.size())
{
root=(TreeNode *)malloc(sizeof(TreeNode));
root->val=j*flag;
root->left=root->right=NULL;
pre->right=root;//根的右孩子即为该数所在节点
p.push(root);//将该数所在节点压入队列
}
}
return head;//返回所建树根节点的地址
}
调用:deserialize(传入序列);
****************************************************************************************************
//判断序列是否具有对称性
bool flag;
void dfs(struct TreeNode *Tleft,struct TreeNode *Tright)
{
if(!flag)
{
return;
}
if(Tleft->val!=Tright->val)//左子树和右子树根节点值不相等,不对称!
{
flag=false;
return;
}
if(Tleft->right&&Tright->left)//“左子树的右子树”和“右子树的左子树”都存在
{
dfs(Tleft->right,Tright->left);//递归,进一步判断“左子树的右子树和右子树的左子树”
}
else if(!Tleft->right&&!Tright->left)//“左子树的右子树”和“右子树的左子树”都不存在,对称
{
;
}
else//“左子树的右子树”或“右子树的左子树”不存在,不对称!
{
flag=false;
return;
}
if(Tleft->left&&Tright->right)//同理判断“左子树的左子树和右子树的右子树”
{
dfs(Tleft->left,Tright->right);
}
else if(!Tleft->left&&!Tright->right)
{
;
}
else
{
flag=false;
return;
}
}
bool isSymmetric(struct TreeNode* root)
{
flag=true;
if(root)
{
if(root->right&&root->left)//树的根节点有左子树和右子树
{
dfs(root->left,root->right);//进一步判断树的左右子树情况
}
else if(!root->right&&!root->left)//树的根节点没有左子树和右子树,对称
{
;
}
else//树的根节点没有左子树或右子树,一定不对称!
{
flag=false;
}
}
return flag;
}
调用:isSymmetric(传入二叉树根节点地址);
****************************************************************************************************
//先序遍历二叉树
void tlr(struct TreeNode* root)
{
if(root)
{
//操作root->val的语句写在这里,本题为“cout<<root->val;”
tlr(root->left);
tlr(root->right);
}
}
调用:tlr(传入二叉树根节点地址);


代码:

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
struct TreeNode {
int val;
struct TreeNode *left,*right;
};
int flag;
TreeNode* init(string data)
{
TreeNode *root,*head,*pre;
queue<TreeNode *> p;
int i=0,j=0,flak=1;
while(data[i]!=' '&&i<data.size())
{
if(data[i]=='n')
{
i+=4;
flak=0;
break;
}
else if(data[i]=='-')
{
flak=-1;
i++;
}
j=j*10+data[i++]-'0';
}
if(!flak)
{
return NULL;
}
else
{
head=(TreeNode *)malloc(sizeof(TreeNode));
head->val=j*flak;
head->left=head->right=NULL;
p.push(head);
}
while(!p.empty())
{
pre=p.front();
p.pop();
j=0;flak=1;i++;
while(data[i]!=' '&&i<data.size())
{
if(data[i]=='n')
{
i+=4;
flak=0;
break;
}
else if(data[i]=='-')
{
flak=-1;
i++;
}
j=j*10+data[i++]-'0';
}
if(!flak&&i<data.size())
{
pre->left=NULL;
}
else if(i<data.size())
{
root=(TreeNode *)malloc(sizeof(TreeNode));
root->val=j*flak;
root->left=root->right=NULL;
pre->left=root;
p.push(root);
}
j=0;flak=1;i++;
while(data[i]!=' '&&i<data.size())
{
if(data[i]=='n')
{
i+=4;
flak=0;
break;
}
else if(data[i]=='-')
{
flak=-1;
i++;
}
j=j*10+data[i++]-'0';
}
if(!flak&&i<data.size())
{
pre->right=NULL;
}
else if(i<data.size())
{
root=(TreeNode *)malloc(sizeof(TreeNode));
root->val=j*flak;
root->left=root->right=NULL;
pre->right=root;
p.push(root);
}
}
return head;
}
void dfs(struct TreeNode *Tleft,struct TreeNode *Tright)
{
if(!flag)
{
return;
}
if(Tleft->val!=Tright->val)
{
flag=false;
return;
}
if(Tleft->right&&Tright->left)
{
dfs(Tleft->right,Tright->left);
}
else if(!Tleft->right&&!Tright->left)
{
;
}
else
{
flag=false;
return;
}
if(Tleft->left&&Tright->right)
{
dfs(Tleft->left,Tright->right);
}
else if(!Tleft->left&&!Tright->right)
{
;
}
else
{
flag=false;
return;
}
}
int isSymmetric(struct TreeNode* root) {
flag=1;
if(root)
{
if(root->right&&root->left)
{
dfs(root->left,root->right);
}
else if(!root->right&&!root->left)
{
;
}
else
{
flag=0;
}
}
return flag;
}
void tlr(struct TreeNode *root)
{
if(!root)
{
return;
}
cout<<root->val;
tlr(root->left);
tlr(root->right);
}
int main()
{
string s;
int num;
struct TreeNode *lead;
while(getline(cin,s))
{
lead=init(s);
num=isSymmetric(lead);
cout<<num<<endl;
if(!num)
{
tlr(lead);
cout<<endl;
}
}
return 0;
}


Problem F: The Clock of Station
题解:简单题
代码:

#include<stdio.h>
int main()
{
int T;
scanf("%d",&T);
while(T--){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
printf("%d\n",(x+y)*z);
}
return 0;
}


Problem G: Count beans will be crazy
题解:(这是一个小学奥数改编的题目)由题意可得本题即求最小公倍数,需考虑到long long,还有直接打出来也是可以的
代码:

#include<stdio.h>
long long gcd(long long n,long long m)
{
long long a=n,b=m,r=a%b;
while(r)
{
a=b;
b=r;
r=a%b;
}
return n/b*m;
}
int main()
{
int n,i;
long long f[45];
f[2]=2;
for(i=3;i<=40;i++)
{
f[i]=gcd(f[i-1],i);
}
while(~scanf("%d",&n))
{
printf("%lld\n",f
-1);
}
return 0;
}


Problem H: Math
题解:此题数据有点虚了,换一种思路可以直接搞。提供本来自己思路的代码
代码:
#include <bits/stdc++.h>

using namespace std;

int T,n,k;

int p[]={2,3,5,7,11,13,17,19,23,29,31};

int sum[11],s[11];

void solve()

{

memset(sum,0,sizeof(sum));

memset(s,0,sizeof(s));

if(n<2)

return;

int i,j;

for(i=0;i<11;++i)

{

j=n;

while(j)

{

sum[i]+=(j/=p[i]);

}

}

}

int calc()

{

if(n<2)

return 0;

int ans=0x7fffffff;

int i,j;

for(i=0;i<11;++i)

{

while(!(k%p[i]))

{

k/=p[i];

++s[i];

}

}

for(i=0;i<11;++i)

{

if(!s[i])

continue;

ans=min(ans,sum[i]/s[i]);

}

return ans;

}

int main()

{

//freopen("test01.in","r",stdin);

//freopen("test01.out","w",stdout);

scanf("%d",&T);

while(T--)

{

scanf("%d%d",&n,&k);

//cin>>n>>k;

solve();

printf("%d\n",calc());

//cout<<calc()<<endl;

}

return 0;

}


Problem I: Jinixin -> Mosu

题意:

在一个二维数组中寻找最长的递增序列长度,该二维数组长度最大可至1000*1000。

想法:

根据题意,大致确定这是一道搜索题,由于寻找的是“最长递增序列长度”,判断应该用迷宫类型的dfs,故直接套模板。



const int N=1000;
int p

,vis

,dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int max,n,m;
void dfs(int x,int y,int t)//迷宫类dfs模板,t为现在“递增序列”的长度
{
int i,a,b;
max=max>t?max:t;//更新max,max为目前“最长递增序列长度”
for(i=0;i<4;i++)
{
a=x+dir[i][0];//根据所处X坐标,产生前进方向的X坐标
b=y+dir[i][1];//根据所处Y坐标,产生前进方向的Y坐标
if(a>=0&&a<n&&b>=0&&b<m&&!vis[a]&&p[a][b]>p[x][y])//判断前进方向坐标是否合法,是否未走过,是否递增
{
vis[a][b]=1;//p[a][b]已经走过
dfs(a,b,t+1);
vis[a][b]=0;//p[a][b]重新标记未走过
}
}
}
int longestIncreaseRoute()
{
int i,j;
max=0;
memset(vis,0,sizeof(vis));//vis用于判断该位置是否已经走过
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&p[i][j]);//输入二维数组
}
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
dfs(i,j,1);//对二维数组每一个位置进行搜索,找出从该位置出发的“最长递增序列长度”
}
}
return max;//返回max,max为“最长递增序列长度”
}
调用:longestIncreaseRoute();

上述方法处理大小为100*100已经费劲了,更别说1000*1000,故我们要想方法提高时效:剪枝or记忆化,下面使用记忆化解决本题。


注:寻找“最长递增序列长度”和寻找“最长递减序列长度”是等价的!
const int N=1000;
int p

,vis

,store

,dir[4][3]={{-1,0},{1,0},{0,-1},{0,1}};//store数组用于记忆化
int dfs(int x,int y)
{
int i,a,b,sum=1;//sum为从该位置出发的“最长递减序列长度”
for(i=0;i<4;i++)
{
a=x+dir[i][0];
b=y+dir[i][1];
dir[i][2]=1;
if(a>=0&&a<n&&b>=0&&b<m&&!vis[a][b]&&p[a][b]<p[x][y])
{
if(store[a][b])//以前搜索过从该位置出发的“最长递减序列长度”,不再重复劳动
{
dir[i][2]=store[a][b]+1;
}
else
{
vis[a][b]=1;
dir[i][2]=dfs(a,b)+1;//dir[i][2]记录从“该位置i方向”出发的“最长递减序列长度”
vis[a][b]=0;
}
}
sum=sum>dir[i][2]?sum:dir[i][2];//四个方向中选取最大的值
}
store[x][y]=sum;//记忆化,从该位置(x,y)出发的“最长递减序列长度”
return sum;
}
int longestIncreaseRoute()
{
int i,j;
int max=0;
memset(vis,0,sizeof(vis));
memset(store,0,sizeof(store));
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&p[i][j]);
}
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(!store[i][j])//如果之前已经搜索过从该位置出发的“最长递减序列长度”,则不再搜索该位置
{
vis[i][j]=1;
dfs(i,j);
vis[i][j]=0;
}
}
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
max=max>store[i][j]?max:store[i][j];//找出“最长递减序列长度”
}
}
return max;
}
调用:longestIncreaseRoute();

“迷宫类dfs+记忆化”可以高效的解决本题。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int M=1005;
int p[M][M],vis[M][M],store[M][M],dir[4][3]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
int dfs(int x,int y)
{
int i,a,b,sum=1;
for(i=0;i<4;i++)
{
a=x+dir[i][0];
b=y+dir[i][1];
dir[i][2]=1;
if(a>=0&&a<n&&b>=0&&b<m&&!vis[a][b]&&p[a][b]<p[x][y])
{
if(store[a][b])
{
dir[i][2]=store[a][b]+1;
}
else
{
vis[a][b]=1;
dir[i][2]=dfs(a,b)+1;
vis[a][b]=0;
}
}
sum=sum>dir[i][2]?sum:dir[i][2];
}
store[x][y]=sum;
return sum;
}
int path()
{
int i,j,max=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(!store[i][j])
{
vis[i][j]=1;
dfs(i,j);
vis[i][j]=0;
}
}
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
max=max>store[i][j]?max:store[i][j];
}
}
return max;
}
int main()
{
//freopen("test1.in","r",stdin);
//freopen("test1.out","w",stdout);
int i,j;
while(~scanf("%d%d",&n,&m))
{
memset(vis,0,sizeof(vis));
memset(store,0,sizeof(store));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&p[i][j]);
}
}
printf("%d\n",path());
}
return 0;
}


[b]Problem J: Jinixin's password

题解:
首先我们判断是否能由n个数构成m。

数据比如 3 0,1 19这种,就不能构成

然后我们就可以贪心了~

最小的数,肯定是由1000000000这种,然后从低位开始增加,直到达到m为止

而最大的数,则是由9999999999这种,从低位到高位,逐渐减小,直到变成m

比如 4 27这组数据

首先贪心最小的:

目前的数 目前的sum

1000 1

1009 10

1099 19

1899 27

贪心最大的:

目前的数 目前的sum

9999 36

9990 27

所以输出1899 9990

代码:

#include<iostream>
#include<stdio.h>
using namespace std;

int flag;
int n,m;
int Min[120];
int Max[120];
void getmin()
{
int sum = 0;
for(int i=1;i<=n;i++)
{
if(i==1)Min[i]=1;
else Min[i]=0;
sum += Min[i];
}
sum = m - sum;
for(int i=n;i>=1;i--)
{
int T = min(sum,9-Min[i]);
sum -= T;
Min[i] += T;
}
if(Min[1]==0)flag = 1;
}
void getmax()
{
int sum = 0;
for(int i=1;i<=n;i++)
{
Max[i]=9;
sum+=Max[i];
}
sum = sum - m;
for(int i=n;i>=1;i--)
{
int T = min(sum,Max[i]);
sum-=T;
Max[i]-=T;
}
if(Max[1]==0)flag = 1;
}
int main()
{
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
scanf("%d%d",&n,&m);
flag = 0;
if(n==1&&m==0)
{
printf("0 0\n");
continue;
}
if(n*9<m)
{
printf("-1 -1\n");
continue;
}
getmin(),getmax();
if(flag)
{
printf("-1 -1\n");
continue;
}
for(int i=1;i<=n;i++)
printf("%d",Min[i]);
printf(" ");
for(int i=1;i<=n;i++)
printf("%d",Max[i]);
printf("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: