奇偶半排序
设计算法将顺序线性表中的所有奇数集中到数组的左边,所有的偶数集中到数组的右边,要求算法的时间复杂度为O(n)。
#include<iostream> #include<algorithm> using namespace std; int main() { int n; while(cin>>n) { int a[n]; for(int i=0; i<n; i++) cin>>a[i]; for(int L=0,R=n-1;L<R;){ while(a[L]&1) ++L; while((L<R)&&!(a[R]&1)) --R; if(L<R) swap(a[L++],a[R--]); } for(int i=0; i<n; i++) cout<<a[i]<<' '; cout<<endl; } return 0; }
#include<iostream> #include<algorithm> using namespace std; int main() { int n; while(cin>>n) { int a[n]; for(int i=0; i<n; i++) cin>>a[i]; for(int i=0,j=0; i<n; i++) if(a[i]&1) swap(a[i],a[j++]); for(int i=0; i<n; i++) cout<<a[i]<<' '; cout<<endl; } return 0; }
循环移动
设将n(n>1)个整数存放到一维数组R中。试设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(X0,X1,…,Xn-1)变换为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1)。
思路:逆序的逆序就是有序,可以通过提前完成一遍操作来“保护”部分元素使其不被乱序,从而完成部分整体交换。
void Swap(int *a, int *b){ *a^=*b; *b^=*a; *a^=*b; } void Reverse(int a[], int L, int R) { int n=((R-L+1)>>1); for(int i=0; i<n; i++) Swap(&a[L+i],&a[R-i]); } void Solve(int a[], int n, int p) { Reverse(a, 0, p-1); Reverse(a, p, n-1); Reverse(a, 0, n-1); }
进制转换
十进制数n 转换成其他进制
#include<iostream> #include<stack> #include<algorithm> using namespace std; int main() { int n,m; while(cin>>n>>m) { stack<int>st; while(n){ st.push(n%m); n/=m; } while(!st.empty()){ cout<<st.top(); st.pop(); } cout<<endl; } return 0; }
这也太水了
栈 中缀转后缀
#include <bits/stdc++.h> using namespace std; int main() { map<char,int>level; level['+']=1; level['-']=1; level['*']=3; level['/']=3; level['(']=0; stack<char>op; string s; while(printf("请输入中缀表达式: \n"),cin>>s) { printf("后缀表达式为:\n"); for(int i=0,n=s.length(); i<n; i++) { if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/') { if(op.empty()) op.push(s[i]); else if(level[s[i]]>level[op.top()]) op.push(s[i]); else { while(!op.empty()&&level[op.top()]>=level[s[i]]) cout<<op.top(),op.pop(); op.push(s[i]); } } else if(s[i]=='(') op.push('('); else if(s[i]==')') { while(op.top()!='(') cout<<op.top(),op.pop(); op.pop(); } else cout<<s[i]; } while(!op.empty()) cout<<op.top(),op.pop(); cout<<endl<<endl; } return 0; }
思路:
从左到右开始扫描中缀表达式
遇到非运算符时,加入后缀表达式
遇到运算符时:
- 若为'(',入栈
- 若为')',则依次将栈中的运算符加入到后缀表达式中,直到出现'('为止,从栈中删除'('
- 若为除括号外的其它运算符,当优先级高于除'('以外的栈顶运算符时,直接入栈;
否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,
直到出现一个比它优先级低或者遇到了一个左括号为止。
后缀表达式计算
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+7; double getnum(string str) { int n=str.size(); int pos=-1; double ans=0.0; for(int i=n-1; i>=0; --i) if(str[i]=='.') { pos=i; break; } if(pos==-1) for(ll i=n-1,j=1; i>=0; --i,j*=10) ans+=(str[i]-'0')*j; else { for(ll i=pos-1,j=1; i>=0; --i,j*=10) ans+=(str[i]-'0')*j; double j=0.1; for(int i=pos+1; i<n; i++,j*=0.1) ans+=(str[i]-'0')*j; } return ans; } int main() { string s; while(getline(cin,s)){ stack<double>st; double ans=0; bool vis=0; for(int i=0,n=s.size(),t; i<n; i++) { if(s[i]>='0'&&s[i]<='9') { for(t=i; i<n&&((s[i]>='0'&&s[i]<='9')||s[i]=='.'); ++i) ; double num=getnum(s.substr(t,i-t)); st.push(num); } else if(s[i]=='+') { if(!vis) ans=st.top(),st.pop(),vis=1; double a=st.top(); st.pop(); ans=a+ans; } else if(s[i]=='-') { if(!vis) { double b=st.top(); st.pop();vis=1; double a=st.top(); st.pop(); ans=a-b; }else { double a=st.top(); st.pop(); ans=ans-a; } } else if(s[i]=='*') { if(!vis) ans=st.top(),st.pop(),vis=1; double a=st.top(); st.pop(); ans=ans*a; } else if(s[i]=='/') { if(!vis) { double b=st.top(); st.pop();vis=1; double a=st.top(); st.pop(); ans=a/b; }else { double a=st.top(); st.pop(); ans=ans/a; } } } cout<<ans<<endl; } return 0; }
下面的是杨文冠的代码(数组倒着用就是了……
#include<bits/stdc++.h> using namespace std; int main() { char str[500]; int cnt=10,top=0; float num=0,num1=0,s[500]; scanf("%[^\n]",str); //读入含空格的模板,直接scanf是做不到的 for(int i=0;str[i]!='#';) { //遍历 if(str[i]>='0'&&str[i]<='9') //如果是数字就转为整数(小数点前面的数就是整数) num=num*10+str[i++]-'0'; else if(str[i]=='.') while(str[++i]!=' ') { //小数点前面的整数加上小数点后面的小数就是这个小数的值了 num+=(float)(str[i]-'0')/cnt; cnt*=10; } else if(str[i]==' ') { //如果当前位置是空格 if(str[i-1]>='0'&&str[i-1]<='9') { //如果前面输入了数字,就进栈并且初始化 s[top++]=num; num=0; cnt=10; } ++i; } else { //出栈进行计算,先出栈的是被操作数(即num1) num1=s[--top]; //--top起到删除栈顶元素的作用 num =s[--top]; switch(str[i++]) { case '+': num+=num1; break; case '-': num-=num1; break; case '*': num*=num1; break; case '/': num/=num1; break; } s[top++]=num; //得到的新数进栈 num=0; } } cout<<s[0]<<endl; //运算结束后只有一个数 return 0; }
出栈序列
递归,二进制枚举
#include <iostream> #include <stack> #include <vector> using namespace std; int num = 0,n; void f(vector<bool>pos, int cnt[], int a[]) { if (cnt[1]) { pos.push_back(1); --cnt[1]; f(pos, cnt, a); ++cnt[1]; pos.pop_back(); } if (cnt[0] && cnt[0] > cnt[1]) { pos.push_back(0); --cnt[0]; f(pos, cnt, a); ++cnt[0]; pos.pop_back(); } if (pos.size() == 2 * n) { stack<int>stk; int j = 0; for (vector<bool>::iterator it = pos.begin(); it != pos.end(); ++it) { if (*it) stk.push(a[j++]); else cout << stk.top() << " ", stk.pop(); } ++num; cout << endl; } } int main() { while (cout << "Input the number: ", cin >> n) { int a[n]; for (int i = 0; i < n; i++) a[i] = 1 + i; int cnt[2] = {n, n-1}; vector<bool>pos; pos.push_back(1); f(pos, cnt, a); cout << "Total: " << num << endl; num = 0; } return 0; }
全排列
#include <bits/stdc++.h> using namespace std; bool chk(vector<int> pushV, vector<int> popV) { stack<int>stk; for (int i=0,j=0; i < pushV.size(); ++i) { stk.push(pushV[i]); while (!stk.empty() && stk.top() == popV[j]) { stk.pop(); ++j; } } return stk.empty(); } int main() { int n; while(~scanf("%d", &n)) { vector<int> p, q; for (int i=1; i<=n; ++i) p.push_back(i), q.push_back(i); do { if (chk(q, p)) { for (auto i : p) printf("%d ",i); printf("\n"); } } while (next_permutation(p.begin(), p.end())); } return 0; }//全排列方案
链表倒数第k
已知一个带有表头结点的单链表,结点结构为(data,link),假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data域的值,并返回1;否则,只返回0。要求:
(1)描述算法的基本设计思想;
(2)描述算法的详细实现步骤;
(3)根据设计思想和实现步骤,采用程序设计语言描述算法,关键之处请给出简要注释。
#include <iostream> #include <cstdio> #include <cstdlib> using namespace std; struct node { int data; struct node *link; }; node *GetList() { node *head=NULL,*rear=NULL; printf("Input List, end with -1 :\n"); int TmpVal=0; while(scanf("%d",&TmpVal),TmpVal!=-1) { node *TmpNode=(node *)malloc(sizeof(node)); TmpNode->data=TmpVal; if (head==NULL) head=TmpNode; else rear->link=TmpNode; rear=TmpNode; } if (rear) rear->link=NULL; return head; } int main() { node *head=GetList(); if (head==NULL) { printf("List is empty!\n"); return 0; } //倒数第k==正数第n-k+1==n-(k-1) //指针i从头指针开始遍历,向前走k-1,指针j不动 //i j同时向前移动 直到i到达n 此时j指向即为所求 int k; while(printf("Input K : "),~scanf("%d",&k)) { node *i=head,*j=head; for(int cnt=1; cnt<=k&&i; ++cnt,i=i->link); for(; i; i=i->link,j=j->link); printf("The K-th last number is: %d\n\n",j->data); } return 0; }
链表公共起始位
假定采用带头节点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀存储空间,例如,“loading”和“being”,如下图所示。
请设计一个时间上尽可能高效的算法,找出由str1和str2所指向两个链表共同后缀的起始位置(如图中字符i所在节点的位置p)。要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++或JAVA语言描述算法,关键为之处给出注释。
(3)说明你所设计算法的时间复杂度。
//将两个str以尾部为基准对齐,指针指向最小点 //两个指针同时右移,直到指向地址相同/指向NULL //指向点即为所求 //O(m+n)线性阶 typedef struct Node{ char data; struct Node *next; } SNODE; SNODE * Findlist(SNODE *str1,SNODE *str2){ int m,n; SNODE *p,*q; m=Listlen(str1); //求单链表str1的长度m n=Listlen(str2); //求单链表str2的长度n for (p=str1;m>n;m--) //若m大,则str1后移m-n个节点 p=p->next; for (q=str2;m<n;n--) //若n大,则str2后移n-m个节点 q=q->next; while (p->next!=NULL && p->next!=q->next){ p=p->next; //p、q两步后移找第一个指针值相等的节点 q=q->next; } return p->next; }
链表排序-归并
链表的高效排序 O(nlogn)
#include<iostream> #include<stack> #include<string> using namespace std; ListNode* sortList(ListNode* head) { if(head==nullptr) return nullptr; if(head->next==nullptr) return head; ListNode *slow = head; //设置一个慢指针 ListNode *fast = head->next; //设置一个快指针 while(fast!=nullptr) { //找出链表的中间节点 fast = fast->next; if(fast==nullptr) break; fast = fast->next; slow = slow->next; } ListNode *list1 = head; ListNode *list2 = slow->next; slow->next = nullptr; ListNode *left = sortList(list1); //递归左归并 ListNode *right = sortList(list2); //递归右归并 ListNode *output = merge(left,right); //合并两个有序链表 return output; } //合并两个有序链表 ListNode* merge(ListNode *left, ListNode *right) { ListNode *out; if(left->val<right->val) { out = left; left = left->next; } else { out = right; right = right->next; } ListNode *p = out; p->next = nullptr; while(left&&right) { if(left->val<right->val) { p->next = left; left = left->next; p = p->next; p->next = nullptr; } else { p->next = right; right = right->next; p = p->next; p->next = nullptr; } } if(left!=nullptr)p->next = left; if(right!=nullptr)p->next = right; return out; }
提取数字
从一个混有英文字母的字符串中提取数字。
#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { int a[105]; int cnt = 0; char ch; do { ch=getchar(); int num = 0; bool vis = 0; while (ch >= '0' && ch <= '9') { num = num * 10 - '0' + ch; //num = num << 3 + num << 1 + ch ^ 48; ch = getchar(); vis = 1; } if (vis) a[cnt++] = num; } while (ch != '\n'); for (int i = 0; i < cnt; ++i) printf("%d ", a[i]); return 0; }
如果考虑大数的话,用字符串/字符数组来做即可。
#include <iostream> #include <string> #include <vector> using namespace std; typedef long long ll; int main() { char ch; vector<string> ans; do { ch = getchar(); string tmp = ""; while (ch >= '0' && ch <= '9') { tmp += ch; ch = getchar(); } if (tmp != "") ans.push_back(tmp); } while (ch != '\n'); for (auto x : ans) cout << x << endl; return 0; }
其他数之积
给你一个数组A[0..n-1],请你在O(n)的时间里构造一个新的数组B[0..n-1],使得:
不能使用除法运算。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e3 + 5; //two pointers int main() { int a[N], b[N], l[N], r[N]; int n; cin >> n; for (int i = 0; i < n; ++i) cin >> a[i]; l[0] = a[0], r[n - 1] = a[n - 1]; for (int i = 1; i < n; ++i) l[i] = l[i - 1] * a[i]; for (int i = n - 2; i >= 0; --i) r[i] = r[i + 1] * a[i]; b[0] = r[1], b[n - 1] = l[n - 2]; for (int i = 1; i < n - 1; ++i) b[i] = l[i - 1] * r[i + 1]; for (int i = 0; i < n; ++i) cout << b[i] << ' '; return 0; }
KMP算法
#include <iostream> #include <string> using namespace std; const int N = 255; void GetNextval(string p, int next[]) {//递归实现优化 int pLen = p.length(); next[0] = -1; int j = -1; int i = 0; while (i < pLen - 1) { if (j == -1 || p[i] == p[j]) { ++i,++j; if (p[i] != p[j]) next[i] = j; else next[i] = next[j]; } else j = next[j]; } } void GetNext(string p, int next[]) {//递归实现 int pLen = p.length(); next[0] = -1; int j = -1; int i = 0; while (i < pLen - 1) { if (j == -1 || p[i] == p[j]) next[++i] = ++j; else j = next[j]; } } void Getnext(string T, int next[]) {//循环实现 int n = T.size(); next[0] = -1; next[1] = 0; for (int i = 1; i < n - 1;) { int t = i; while (i < n - 1 && T[i] == T[i - t]) next[++i] = i - t; if (i == t) next[++i] = 0; } } int KMP(string a, string b, int next[]) { int i = 0, j = 0, lena = a.length(), lenb = b.length(); while (i < lena && j < lenb) { if (j == -1 || a[i] == b[j]) ++i, ++j; else j = next[j]; } if (j == lenb) return i - j; else return -1; } int main() { string a = "ababaaaba"; string b = "ababaaaba"; int next[N]; for (int i = 0; i < b.length(); i++) printf("%3c", b[i]); cout << endl; Getnext(b, next); for (int i = 0; i < b.length(); i++) printf("%3d", next[i]); cout << endl; GetNext(b, next); for (int i = 0; i < b.length(); i++) printf("%3d", next[i]); cout << endl; return 0; }
优化后的输出结果
-1 -1 1 0 0 -1 -1 1 3 0 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 1 0 -1 3 -1
课本式KMP的结果
//严蔚敏原版 #include <iostream> #include <string> using namespace std; const int N = 255; void GetNextval(string p, int next[]) { int i=1,j=0; next[1]=0; while(i<p.length()) { if(j==0||p[i]==p[j])next[++i]=++j; else j=next[j]; } } int main() { string a = "bbdcfbbdac"; string b = "aaaaaaa"; string c = "babbabab"; int next[N]; cout << endl; GetNextval(a, next); for (int i = 1; i < a.length(); i++) printf("%3d", next[i]); cout << endl; GetNextval(b, next); for (int i = 1; i < b.length(); i++) printf("%3d", next[i]); cout << endl; GetNextval(c, next); for (int i = 1; i < c.length(); i++) printf("%3d", next[i]); cout << endl; return 0; } 运行结果: 0 1 1 1 1 2 2 3 1 0 1 2 3 4 5 0 1 1 1 2 3 2
//严蔚敏改进 #include <iostream> #include <string> using namespace std; const int N = 255; void GetNextval(string p, int next[]) { int i=1,j=0; next[1]=0; while(i<p.length()) { if(j==0||p[i]==p[j]){ ++i,++j; if(p[i]!=p[j]) next[i]=j; else next[i]=next[j]; } else j=next[j]; } } int main() { string a = "bbdcfbbdac"; string b = "aaaaaaa"; string c = "babbabab"; int next[N]; cout << endl; GetNextval(a, next); for (int i = 1; i < a.length(); i++) printf("%3d", next[i]); cout << endl; GetNextval(b, next); for (int i = 1; i < b.length(); i++) printf("%3d", next[i]); cout << endl; GetNextval(c, next); for (int i = 1; i < c.length(); i++) printf("%3d", next[i]); cout << endl; return 0; } 运行结果: 0 1 1 1 0 2 1 3 1 0 0 0 0 0 0 0 1 1 0 1 3 1
这是因为超级老的老教材,清华大学出版社《数据结构》第二版默认字符串第一个字符存数组长度,所以next数组的首下标也是从0开始……
其实很多东西本身并不复杂,而是有些“学者”在传播的时候把它弄复杂了。
推荐这一篇博客,我们都是跟着这个学的。
https://blog.csdn.net/v_july_v/article/details/7041827#
应要求写一下这个。
按照优化后的KMP算法生成P串next数组为 -1 -1 1
ababbaabaa aa aa a aab
括号/层号表示构建树
复古了一下,用了次c语言。
#include <stdio.h> const int maxn = 3; const int maxsize = 20; typedef char datatype; typedef struct treenode { datatype data; int child[maxn]; } treenode; typedef struct levelnode { datatype data; int level; } levelnode; void leveltotree(int length, levelnode ltree[], int *root, treenode tree[]) { for (int i = 0; i < length; ++i) for (int j = 0; j < maxn; ++j) tree[i].child[j] = -1; *root = 0; tree[0].data = ltree[0].data; //初始化 for (int i = 1, j = i - 1, tmp = j; i < length; ++i) { tree[i].data = ltree[i].data; //本个节点 if (ltree[i].level > ltree[i - 1].level) { tmp = j; j = i - 1; for (int k = 0; tree[j].child[k] != -1; ++k) tree[j].child[k] = i; //将自己连接到双亲节点上 } else if (ltree[i].level > ltree[j].level) { //纳入孩子 tree[j].child[0] = i; } else { j = tmp; for (int k = 0; tree[j].child[k] != -1; ++k) tree[j].child[k] = i; //将自己连接到双亲节点上 } }
二叉树的遍历和构建
#include <memory.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef char TreeElemType; typedef struct BinTreeNode { TreeElemType Data; struct BinTreeNode *Lchild, *Rchild; } BinTreeNode, *BinTree; void CreatBinTree(BinTree *T) { // input as PreOrderTraversal // eg. AB#D##C## TreeElemType ch; scanf("%c", &ch); if (ch == '#') *T = NULL; else { *T = (BinTree)malloc(sizeof(BinTreeNode)); if (!*T) exit(-1); (*T)->Data = ch; CreatBinTree(&(*T)->Lchild); CreatBinTree(&(*T)->Rchild); } } void PreOrderTraverse(BinTree T) { if (T == NULL) return; printf("%c", T->Data); PreOrderTraverse(T->Lchild); PreOrderTraverse(T->Rchild); } // To construct a binary tree through post-order traversal, // the sequence needs to be read from back to front. // Root ---> RChild ---> LChild void InOrderTraverse(BinTree T) { if (T == NULL) return; InOrderTraverse(T->Lchild); printf("%c", T->Data); InOrderTraverse(T->Rchild); } void PostOrderTraverse(BinTree T) { if (T == NULL) return; PostOrderTraverse(T->Lchild); PostOrderTraverse(T->Rchild); printf("%c", T->Data); }
穿线二叉树
上图是一个常规的二叉树结构。它有很多指针指向了NULL。我们可以利用这些空的指针,来更快地实现先序/中序/后序的访问。
具体怎么做呢?其实很简单,就是让每一个有空指针的节点,左指针指向前驱,右指针指向后继。
前序+中序推树
(不带虚空节点)
#include <stdio.h> const int N = 1010; int pre[N], in[N], post[N]; int k; struct node { int value; node *l, *r; node(int value = 0, node *l = NULL, node *r = NULL) : value(value), l(l), r(r) {} }; void buildtree(int l, int r, int &t, node *&root) { int flag = -1; for (int i = l; i <= r; ++i) if (in[i] == pre[t]) { flag = i; break; } if (flag == -1) return; root = new node(pre[t++]); if (flag > l) buildtree(l, flag - 1, t, root->l); if (flag < r) buildtree(flag + 1, r, t, root->r); } void preorder(node *root) { if (root != NULL) { pre[k++] = root->value; preorder(root->l); preorder(root->r); } } void inorder(node *root) { if (root != NULL) { inorder(root->l); post[k++] = root->value; inorder(root->r); } } void postorder(node *root) { if (root != NULL) { postorder(root->l); postorder(root->r); post[k++] = root->value; } } void removetree(node *root) { if (root == NULL) return; removetree(root->l); removetree(root->r); delete root; } int main() { int n; while (~scanf("%d", &n)) { for (int i = 1; i <= n; ++i) scanf("%d", &pre[i]); for (int i = 1; i <= n; ++i) scanf("%d", &in[i]); node *root; int t = 1; buildtree(1, n, t, root); k = 0; postorder(root); for (int i = 0; i < k; ++i) printf("%d%c", post[i], i == k - 1 ? '\n' : ' '); removetree(root); } return 0; }
后序+中序
/*test data 9 7 4 2 8 9 5 6 3 1 4 7 2 1 8 5 9 3 6 1 2 4 7 3 5 8 9 6 */ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1010; int pre[N], in[N], post[N]; int k; struct node { int value; node *l, *r; node(int value = 0, node *l = NULL, node *r = NULL) : value(value), l(l), r(r) {} }; void buildtree(int l, int r, int &t, node *&root) { int flag = -1; for (int i = l; i <= r; ++i) if (in[i] == post[t]) { flag = i; break; } if (flag == -1) return; root = new node(post[t--]); if (flag < r) buildtree(flag + 1, r, t, root->r); if (flag > l) buildtree(l, flag - 1, t, root->l); } void preorder(node *root) { if (root != NULL) { pre[k++] = root->value; preorder(root->l); preorder(root->r); } } void inorder(node *root) { if (root != NULL) { inorder(root->l); post[k++] = root->value; inorder(root->r); } } void postorder(node *root) { if (root != NULL) { postorder(root->l); postorder(root->r); post[k++] = root->value; } } void removetree(node *root) { if (root == NULL) return; removetree(root->l); removetree(root->r); delete root; } int main() { int n; while (~scanf("%d", &n)) { for (int i = 1; i <= n; ++i) scanf("%d", &post[i]); for (int i = 1; i <= n; ++i) scanf("%d", &in[i]); node *root; int t = n; buildtree(1, n, t, root); k = 0; preorder(root); for (int i = 0; i < k; ++i) printf("%d%c", pre[i], i == k - 1 ? '\n' : ' '); removetree(root); } return 0; }
小学奥数 填数字
1到9,填成两个三位数之和等于另一个三位数。
数量级太小,全排列查一遍就行了
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 7; const ll mod = 1e9 + 7; int main() { vector<int> a; for (int i = 1; i < 10; ++i) a.push_back(i); vector<vector<int>> ans; do { ans.push_back(a); } while (next_permutation(a.begin(), a.end())); for (vector<vector<int>>::iterator it = ans.begin(); it != ans.end(); ++it) { vector<int>::iterator iter = (*it).begin(); int a = iter[0] * 100 + iter[1] * 10 + iter[2]; int b = iter[3] * 100 + iter[4] * 10 + iter[5]; int c = iter[6] * 100 + iter[7] * 10 + iter[8]; if (a + b == c) { for (int i = 0; i < 9; ++i) cout << iter[i] << " "; cout << endl; } } return 0; }
其实也不用存,只是熟悉一下迭代器写法。
vector<int> a; for (int i = 1; i < 10; ++i) a.push_back(i); do { if (a[0] * 100 + a[1] * 10 + a[2] + a[3] * 100 + a[4] * 10 + a[5] == a[6] * 100 + a[7] * 10 + a[8]) for (int i = 0; i < 9; ++i) printf("%d%c", a[i], i == 8 ? '\n' : ' '); } while (next_permutation(a.begin(), a.end()));