@Moritz
2019-03-26T04:26:10.000000Z
字数 6452
阅读 469
aoapc_2nd
C++
所有文稿
输入正整数n,从小到大的顺序输出所有形如abcde/fghij=n
的表达式,其中a~j恰好为数字0-9的一个排列。
思路:即使参考了书上的思路,看上去很容易实现,实际上真正上手写出来代码花了几个多小时,再次深刻地体现了现在纸上写好细节思路的重要性,以及对应功能用函数实现使到代码简化的必要性。
/*19:48*/
/*21:04*/
#include <iostream>
#include <cmath>
using namespace std;
int a[20],n,cnt=0;
int turn_5(int x=1,int y=5){//把除数(数组的前五个数)化成整数
int tot=0;
float e=0.0;
for(int i=x;i<=y;i++){
tot=tot+a[i]*pow(10,e);
//printf("i=%d tot=%d\n",i,tot);
e=e+1.0;
}
return tot;
}
int devi(int x,int n,int a=5){//把被除数拆成5个数字,以便判重
int e=1;
for(int i=1;i<n;i++) e*=10;
x/=e;
x=x%10;
return x;
}
void find_5(int cur){//生成除数的所有可能
/*递归边界,判重*/
if (cur>5) {
if (turn_5()*n<=99999) {
bool ok=true;
int x=turn_5()*n;
for(int i=6;i<=10;i++){
a[i]=devi(x,i-5,5);
for(int j=1;j<i;j++){
if (a[j]==a[i]){
//printf("turn_5=%d x=%d a[%d]=a[%d]==%d\n",turn_5(),x,i,j,a[i]);
ok=false;
break;
}
}
}
if (ok){//如果不重复 输出
if (cnt++)
cout<<endl;
for(int i=10;i>=6;i--) cout<<a[i];
cout<<'\\';
for(int i=5;i>=1;i--) cout<<a[i];
cout<<'\='<<n;
}
}
return;
}
/*生成除数的排列*/
for(int i=0;i<=9;i++){
bool ok=true;
for(int j=1;j<cur;j++){
if (a[j]==i){
ok=false;
break;
}
}
if (ok){
a[cur]=i;
find_5(cur+1);
}
}
}
int main(){
cin>>n;
memset(a,0,sizeof(a));
find_5(1);
system("pause");
return 0;
}
出现的几个难题(自己挖的坑):
输入n个元素组成的序列S,找出一个乘积最大的连续子序列,如果最大的乘积不是正数,则输出0。(1<=n<=10,-10<=Si<=10)
思路:直接循环枚举,没啥难度,反而一开始还想多了,开始写solve
递归函数……
/*21:32*/
/*21:44*/
#include <iostream>
using namespace std;
long long max_mu=0;
int a[20],n;
int mu(int x,int y){
int tot=1;
for(int i=x;i<=y;i++) tot*=a[i];
return tot;
}
int main(){
int en=0;
while(cin>>n){
memset(a,0,sizeof(a));
max_mu=0;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n-1;i++){
for(int j=1;j<n;j++){
if (j-i>=1){
max_mu=(max_mu>mu(i,j)?max_mu:mu(i,j));
}
}
}
if(en++) cout<<endl;
cout<<max_mu;
}
system("pause");
return 0;
}
写就是了
/*21:49*/
/*21:57*/
#include <iostream>
using namespace std;
const int maxn=1000;
int a[maxn],n;
void print_per(int cur){
if (cur>=n){
cout<<"(";
int co=0;
for(int i=0;i<n;i++){
if (co++) cout<<",";
cout<<a[i];
}
cout<<")"<<endl;
return;
}
for(int i=1;i<=n;i++){
bool ok=true;
for(int j=0;j<cur;j++){
if (a[j]==i){
ok=false;
break;
}
}
if(ok){
a[cur]=i;
print_per(cur+1);
}
}
}
int main(){
cin>>n;
print_per(0);
system("pause");
return 0;
}
/*22:04*/
/*22:23*/
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1000;
int a[maxn],n,p[maxn],re[10];
int count(int x,int cur){//优化
int tot=0;
for(int i=0;i<cur;i++){
if (a[i]==x) tot++;}
return tot;
}
void print_per(int cur){
if (cur>=n){
cout<<"(";
int co=0;
for(int i=0;i<n;i++){
if (co++) cout<<",";
cout<<a[i];
}
cout<<")"<<endl;
return;
}
for(int i=0;i<=n;i++){//从p0-pn取值
if (i==0||p[i]!=p[i-1]){//注意!!!:此举避免了出现重复的排列,例如(1,1,1)的情况
if (count(p[i],cur)<re[p[i]]){//如果现有a元素中p元素各值的数量未满
a[cur]=p[i];
print_per(cur+1);
}
}
}
}
int main(){
cin>>n;
memset(p,0,sizeof(p));
memset(a,0,sizeof(a));
memset(re,0,sizeof(re));
for(int i=0;i<n;i++){
cin>>p[i];
re[p[i]]++;//优化书中代码,只需统计一次p中p[i]出现的次数
}
sort(p,p+n);
print_per(0);
system("pause");
return 0;
}
看了下,没怎么管。 -2019.3.8
看完分析之后试写了一下
/*10:14*/
/*10:58*/
#include <iostream>
#include <cstdio>
#include <set>
#include <map>
#include <string>
#include <utility>
using namespace std;
int a1[20],a2[20],cnt=0;
pair<int,int> point[10];//存放皇后的坐标
map<set<pair<int,int> > ,int> m;
bool an1(int x,int y,int cur){//判断(x,y)点主对角线上是否有皇后
/*if (a1[y-x+7]==0) return true;
return false;*/
for(int i=1;i<cur;i++){
if (point[i].first+point[i].second==x+y) return false;
}
return true;
}
bool an2(int x,int y,int cur){//判断的对角线上是否有皇后
/*if (a2[y+x]==0) return true;
return false;*/
for(int i=1;i<cur;i++){
if (point[i].first-point[i].second==x-y) return false;
}
return true;
}
void search(int cur){
if (cur>8){
set<pair<int,int>> p;
for(int i=1;i<=8;i++){
p.insert(make_pair((point[i]).first,(point[i]).second));
}
if (!m.count(p)){
m[p]=1;
printf("Case %d\n",++cnt);
for(int i=1;i<=8;i++){
printf("Point %d:(%d,%d)\n",i,point[i].first,point[i].second);
}
}
return;
}
for(int x=1;x<=8;x++){//确定x坐标
bool ok_x=true;
for(int i=1;i<cur;i++){//y坐标判重
if ((point[i]).first==x){
ok_x=false;
break;
}
}
if (ok_x){
for(int y=1;y<=8;y++){
bool ok_y=true;
for(int j=1;j<cur;j++){//x坐标判重
if ((point[j]).second==y){
ok_y=false;
break;
}
}
if (ok_y){
if (an1(x,y,cur)&&an2(x,y,cur)){
point[cur].first=x;
point[cur].second=y;
search(cur+1);
}}}}}}
int main(){
memset(a1,0,sizeof(a1));
memset(a2,0,sizeof(a2));
memset(point,0,sizeof(point));
search(1);
system("pause");
return 0;
}
/*
(输出的点和坐标已省略,共92组解
Process returned 0 (0x0) execution time : 57.719 s
Press any key to continue.
*/
没有意识到,其实直接规定每行有一个皇后就可以了,不用进行y坐标的判重,算法复杂度明显提高,运行时间将近一分钟,并且还需要运用map进行判重。
优化之后:
/*2.1 去掉了map判重*/
#include <iostream>
#include <cstdio>
#include <string.h>
#include <utility>
using namespace std;
int cnt=0;
pair<int,int> point[10];//存放皇后的坐标
bool an1(int x,int y,int cur){//判断(x,y)点主对角线上是否有皇后
for(int i=1;i<cur;i++){
if (point[i].first+point[i].second==x+y) return false;
}
return true;
}
bool an2(int x,int y,int cur){//判断的对角线上是否有皇后
for(int i=1;i<cur;i++){
if (point[i].first-point[i].second==x-y) return false;
}
return true;
}
void search(int cur){
if (cur>8){
printf("Case %d\n",++cnt);
for(int i=1;i<=8;i++){
printf("Point %d:(%d,%d)\n",i,point[i].first,point[i].second);
}
return;
}
for(int y=1;y<=8;y++){
bool ok_y=true;
for(int j=1;j<cur;j++){//x坐标判重
if ((point[j]).second==y){
ok_y=false;
break;
}
}
if (ok_y){
if (an1(cur,y,cur)&&an2(cur,y,cur)){
point[cur].first=cur;
point[cur].second=y;
search(cur+1);
}
}
}
}
int main(){
memset(point,0,sizeof(point));
search(1);
system("pause");
return 0;
}
/*至此,完成,11:11
Process returned 0 (0x0) execution time : 0.156 s
Press any key to continue.
*/
一开始理解出现偏差,误以为第k小的困难串长度等于k,输入为30 3
的时候输出错误,然后修改得乱七八糟
/*10:27*/
#include <iostream>
#include <string>
using namespace std;
int n,l;
string str(80,'0'),str2(80,'0');//string初始化,否则str[cur-1]=c语句会造成溢出
void solve(int cur){
if (cur>n){
cout<<str<<endl;
system("pause");
return;
}
else{
for(int i=0;i<l;i++){
char c='A'+i;
bool ok=true;
cout<<"enter loop cur="<<cur<<endl;
for(int len=1;len<cur/2;len++){
if (str.substr(cur-len)==str.substr(cur-len*2,len)){
cout<<str.substr(cur-len)<<endl;
cout<<str.substr(cur-len*2,len)<<endl;
cout<<str<<endl;
ok=false;
break;
}
}
cout<<"loop ok cur="<<cur<<endl;
if (ok){
str[cur-1]=c;
solve(cur+1);
}
}
}
}
int main(){
cin>>n>>l;
//solve(1);
int cur=1,cnt=0;
while(cnt<=n){
bool ok=true;
char c;
for(int i=0;i<l;i++){
c='A'+i;
str2[cur-1]=c;
//cout<<"enter loop cur="<<cur<<endl;
ok=true;
for(int len=1;len<=cur/2;len++){
//cout<<str.substr(cur-len,len)<<endl;
//cout<<str.substr(cur-len*2,len)<<endl;
if (str2.substr(cur-len,len)==str2.substr(cur-len*2,len)){
//cout<<str.substr(cur-len,len)<<endl;
//cout<<str.substr(cur-len*2,len)<<endl;
ok=false;
break;
}
}
if (ok) {
//cout<<"loop ok cur="<<cur<<endl;
cnt++;
str[cur-1]=c;
str2[cur-1]=c;
}
}
cur++;
}
for(int i=0;i<cur;i++) cout<<str[i];
system("pause");
return 0;
}
/*运行结果:
7 3
CBBB0请按任意键继续. . .
不改了,看书*/
书上照搬,发现30 3
无输出
挖个坑先
2019.3.8