7-1 好数 (15 分)
输入样例
3
1
91
50
输出样例
No 7
1 2
Yes
1 9
5 6
No 52
2 6
C++
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
int hao[10050];
memset(hao,0,sizeof hao);
for(int i=1;i<=100;i++)
{
for(int j=i+1;j<=100;j++)
{
int t=i*i+i*j+j*j;
if(t<=10050)
hao[t]=1;
}
}
int n,t;
cin>>n;
for(int f=1;f<=n;f++)
{
cin>>t;
if(hao[t]==0)
{
while(hao[t]==0)
{
t++;
}
printf("No %d\n",t);
goto loop;
}
else
{
printf("Yes\n");
loop:
for(int i=1;i<=100;i++)
{
for(int j=i+1;j<=100;j++)
{
int m=i*i+i*j+j*j;
if(m==t)
printf("%d %d\n",i,j);
}
}
}
}
}
7-2 数以类聚 (20 分)
我们把所有各位数字的乘积相同的数归为一类。例如 1362 和 2332 就是同一类,因为 1×3×6×2=2×3×3×2。给定 N个正整数,请你判断它们可以被归成多少不同的类?
输入格式:输入在第一行给出一个正整数 N(≤105),第二行给出 N 个不超过 107 的正整数,数字间以空格分隔。
输出格式:
在一行中输出 N 个给定的整数可以归类的数量、以及规模最大的类中最小的乘积。数字间以一个空格分隔。
输入样例
10
1234 98 329 9552 47621 8862 5539 2333 5365 463
输出样例
7 54
C++
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
map<int,int>wz;
struct node
{
int num;
int a;
}t[1000050];
bool cmp(node a,node b)
{
if(a.num==b.num)
{
return a.a<b.a;
}
return a.num>b.num;
}
int main()
{
int n,cnt=0;
cin>>n;
for(int i=1;i<=n;i++)
{
int s,sum=1;
cin>>s;
while(s)
{
sum=sum*(s%10);
s/=10;
}
if(wz[sum])
{
t[wz[sum]].num++;
}
else
{
t[++cnt].num=1;
t[cnt].a=sum;
wz[sum]=cnt;
}
}
sort(t+1,t+cnt+1,cmp);
printf("%d %d",cnt,t[1].a);
}
7-3 自定义判题程序 (20 分)
在每次允许插入、删除、修改一个字符的前提下,用最少的动作把一个字符串变成另一个字符串,是一道著名的可以用动态规划解决的问题。但判题的麻烦之处在于,虽然最小代价是唯一的,但变换方法却是不唯一的。例如把 PAT
变成 PTA
最少需要 2 步,可以保持第 1 个字母不变,修改后面 2 个字母,也可以保持第 1、2 个字母不变,在 A
前面插入 T
,后面删除 T
。由于拼题 A 系统的默认判题程序只能通过比对输出文件来判断对错,对这种正确答案输出不唯一的题目就不能处理了,需要出题者额外编写一个自定义判题程序来解决问题。
本题就请你编写这个自定义判题程序,读入两个字符串和用户程序产生的输出结果,判断他们的程序输出是否正确。
输入格式:
输入首先在前两行分别给出两个不超过 1000 个字符、以回车结束的非空字符串,第 1 行对应初始字符串,第 2 行对应目标字符串。
随后一行给出一个正整数 N(≤100),为需要判断的提交数。
接下来是 N 个提交的输出结果,每个结果占 2 行:第 1 行给出一个整数 K(不超出 32 位 int 的范围),为用户输出的动作数;第 2 行顺次描述对初始字符串的每个字符所做的操作:
如果这个字符不变,则在对应位置输出 0
如果这个字符被删除,则在对应位置输出 1
如果这个字符被改变,则在对应位置输出 2
如果这个字符前面或者后面插入了一个字符,则在插入的位置输出 3
注意我们要求用户提交的行首尾和数字间均无空格,所以如果有多余空格应判为错误。
题目保证这个操作序列不为空。
输出格式:
对每个正确的提交,在一行中输出 AC
;否则输出 WA
。
注意:这里并不要求你会用动态规划求出最优解。所以对“正确提交”的判断,并不以动态规划求出的最优解为根据! 对于用户输出的 K,如果其操作序列的确给出了 K 步操作并可以完成字符串的变换,则称为一个“可行解”。所谓“正确提交”,是指所有提交的可行解中的最优解。
输入样例
This is a test.
Tom is a cat.
6
8
02330001100022100
8
11113330000001113300
6
022100000012200
5
033310000000200
6
0 2 2 1 000000 1 2 2 00
6
012200000022100
输出样例
WA
WA
AC
WA
WA
AC
某dalao的AC代码
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int main()
{
int t, k[11000];
string a, b, s;
int maxx = 9999999;
getline(cin, a);
getline(cin, b);
cin >> t;
for (int kk = 0; kk < t; kk++)
{
int n, j = 0, f = 0, cnt = 0;
cin >> n;
string c;
getchar();
getline(cin, s);
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '0')
{
c += a[j];
j++;
}
else if (s[i] == '1')
{
j++;
cnt++;
}
else if (s[i] == '2')
{
c += '^';
j++;
cnt++;
}
else if (s[i] == '3')
{
c += '^';
cnt++;
}
else
{
f = 1;
}
}
if (c.size() != b.size() || cnt != n)
f = 1;
for (int i = 0; i < b.size(); i++)
{
if (c[i] == b[i] || c[i] == '^') continue;
else f = 1;
}
if (f == 0)
{
k[kk] = n;
if (n < maxx) maxx = n;
}
else
{
k[kk] = -1;
}
}
for (int i = 0; i < t; i++)
{
if (k[i] == maxx) cout << "AC" << endl;
else cout << "WA" << endl;
}
system("pause");
return 0;
}
mine:
这题最终也没把题搞明白,细节也特别多,看榜上的大佬也是一分一分上去的,只拿到了12分
C++ 12分代码
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a,b,c,bb=" ",aa=" ";
int n,k;
int lea,leb;//a的原始长度 b的原始长度
getline(cin,a);
getline(cin,b);
lea=a.size();
leb=b.size();
a+=aa;
b+=bb;
cin>>n;
for(int f=1;f<=n;f++)
{
bool pd=1;
int cnt=0,cn1=0,cn2=0;//cnt判断出现123的个数 cn1 a串的进度 cn2 b串的进度
cin>>k;
getchar();
getline(cin,c);
int s3=0,s1=0;
for(int i=0;i<c.size();i++)
{
if(c[i]=='0') //0
{
if(s3>s1)
{
cn2+=(s3-s1);
s3=s1=0;
}
else if(s3<s1)
{
cn1+=(s1-s3);
s3=s1=0;
}
if(a[cn1]==b[cn2])
{
cn1++;
cn2++;
}
else
{
printf("WA\n");
pd=0;
break;
}
}
else if(c[i]=='1')
{
s1++;
//cn1++;
cnt++;
}
else if(c[i]=='2')
{
if(s3>s1)
{
cn2+=(s3-s1);
s3=s1=0;
}
else if(s3<s1)
{
cn1+=(s1-s3);
s3=s1=0;
}
cn1++;
cn2++;
cnt++;
}
else if(c[i]=='3')
{
s3++;
cnt++;
//cn2++;
}
else
{
printf("WA\n");
pd=0;
break;
}
if(cnt>k||cn1>lea||cn2>leb)
{
printf("WA\n");
pd=0;
break;
}
}
if(pd)
{
if(a[cn1+1]!=b[cn2+1]||a[cn1+2]!=b[cn2+2])
{
printf("WA\n");
}
else printf("AC\n");
}
}
}
7-4 数组与链表 (20 分)
输入样例
6 7
2048 5
128 6
4016 10
1024 7
3072 12
9332 10
2 12 25 50 28 8 39
输出样例
2056
4020
1040
Illegal Access
3072
140
3116
5
样例说明:
访问 A[2] 即 A0[2],元素的地址就是 2048+2×4=2056。
访问 A[12],则只加开 A1 不够,需要加开 A2,其初始位置 h2=4016,则 A[12]=A2[1] 的地址就是 4016+1×4=4020。
访问 A[25],则必须加开 A3,其初始位置 h3=1024,则 A[25]=A3[4] 的地址就是 1024+4×4=1040。
访问 A[50] 超出了允许创建的数组的最大边界,所以是非法访问,新数组未创建。
访问 A[28],则必须加开 A4,其初始位置 h4=3072,则 A[28]=A4[0] 的地址就是 3072。
访问 A[8]=A1[3],所以地址是 128+3×4=140。
访问 A[39]=A4[11],地址就是 3072+11×4=3116。
上述访问一共创建了 5 个数组。
C++
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
int add;
int size;
}t[100050];
vector<int>wz(10050000);
//map<int,int>wz;
signed main()
{
int n,k,all=0;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
scanf("%d",&t[i].add);
scanf("%d",&t[i].size);
all+=t[i].size;
wz[i]=all-1;
}
all--;
wz[0]=-1;
int m,use=0,ans=0,ma=1;
for(int i=1;i<=k;i++)
{
scanf("%d",&m);
if(m>all)
{
printf("Illegal Access\n");
continue;
}
int w;
for(int i=1;i<=n;i++)
{
if(m<=wz[i])
{
w=i;
break;
}
}
ma=max(ma,w);
printf("%d\n",t[w].add+(m-wz[w-1]-1)*4);
}
printf("%d",ma);
}
7-5 取帽子 (25 分)
输入样例
10
12 19 13 11 15 18 17 14 16 20
67 90 180 98 87 105 76 88 150 124
输出样例
3 4 8 6 10 2 1 5 9 7
样例说明:
第一顶帽子的尺寸是最大的 20,所以对应第 3 个人的最大体重 180,于是第 3 个人排在最前面。
第二顶帽子的尺寸是第 6 小的 16,对应第 6 小的体重 98,是第 4 个人,于是第 4 个人下一个走。
以此类推。
C++
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
struct node
{
int num;
int a;
}t[10050];
map<int,int>s;
//int s[10050];
struct mao
{
int size;
int num;
int weici;
}ma[10050];
mao use[10050];
bool cmp1(mao a,mao b)
{
return a.size>b.size;
}
bool cmp2(node a,node b)
{
return a.num>b.num;
}
int main()
{
int n,m[10050];
cin>>n;
for(int i=n;i>0;i--)
{
cin>>ma[i].size;
ma[i].num=i;
use[i].size=ma[i].size;
use[i].num=i;
}
sort(use+1,use+1+n,cmp1);
for(int i=1;i<=n;i++)
{
s[use[i].size]=i;
}
for(int i=1;i<=n;i++)
{
cin>>t[i].num;
t[i].a=i;
}
sort(t+1,t+n+1,cmp2);
for(int i=1;i<=n;i++)
{
int cn=ma[i].size;
cn=s[cn];
cn=t[cn].a;
printf("%d",cn);
if(i!=n) printf(" ");
}
}
总结
这次乙级挺遗憾的,计划都是冲着满分去的,但是卡在了第三题上,看榜上的大佬们也是一分一分上去的,这题也真的是感觉题也没搞明白。
以后乙级应该会成为遗憾了吧,要去准备甲级了。不过也幸好达到了90分以上,拿到了十几名,只卡在了一道题上。还是自己水平太低了!