注意:用long long 存答案
P2241 统计方形(数据加强版)
例:2(n) * 3(m):枚举 i 从0~n-1;j从0~m-1
边长为 1 的正方形:2 * 3 个;(n - 0)*(m - 0)
边长为 2 的正方形:1 * 2个;(n - 1)*(m - 1)
其他为 长方形;(n - i)*(m - j)
#include
using namespace std;long long n, m, suma, sumb;
int main()
{cin >> n >> m;for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(j == i) suma += (n - i)*(m - j);else sumb += (n - i)*(m - j);}}cout << suma << " " << sumb << endl;return 0;
}
P2089 烤鸡
有 10 种配料,每种配料可以放 1 到 3 克,任意烤鸡的美味程度为所有配料质量之和
#include
using namespace std;int n, a[10010][10], t[10], m;//m 方案数, 第 i种材料 t[i]克
void dfs(int sum, int k){// k 种配料,美味程度 sum if(k == 10 && sum == n){for(int i = 0; i < 10; i++){a[m][i] = t[i];} m++;}if(k < 10 && sum < n){for(int j = 1; j <= 3; j++){t[k] = j;dfs(sum + j, k + 1);}}
}
int main()
{cin >> n;dfs(0, 0);cout << m << endl;for(int i = 0; i < m; i++){for(int j = 0; j < 10; j++){cout << a[i][j] << " ";}cout << endl;}return 0;
}
P1618 三连击(升级版)
保证 A#include
using namespace std;int a, b, c, f, vis[10];
double ta, tb, tc;
void fun(int n){while(n){vis[n % 10]++;n /= 10;}
}
int main()
{cin >> a >> b >> c;for(int i = 123; i <= 987; i++){memset(vis, 0, sizeof(vis));ta = i;tb = ta / a * b;//ta:tb = a:btc = ta / a * c;if(int(tb) != tb || int(tc) != tc || tc > 987)continue;fun(ta), fun(tb), fun(tc);if(vis[1]==1 && vis[2]==1 && vis[3]==1 && vis[4]==1 && vis[4]==1 && vis[6]==1 && vis[7]==1 && vis[8]==1 && vis[9]==1){cout << ta << " " << tb << " " << tc << endl;f = 1;}}if(! f) cout << "No!!!" << endl; return 0;
}
P1157 组合的输出
#include
using namespace std;int n, r, a[25], ans[25];
void dfs(int id, int num){if(num == r){for(int i = 0; i < num; i++)cout << setw(3) << ans[i];cout << endl; }else if(num < r){for(int i = id + 1; i <= n; i++){ans[num] = a[i];dfs(i, num + 1);}}
}
int main()
{cin >> n >> r;for(int i = 1; i <= n; i++) a[i] = i;dfs(0, 0);return 0;
}
P1706 全排列问题
#include
using namespace std;int n, a[10], vis[10], ans[10];
void dfs(int num){if(num == n){for(int i = 0; i < num; i++)cout << setw(5) << ans[i];cout << endl;}if(num < n){for(int i = 1; i <= n; i++){if(! vis[i]){ans[num] = a[i], vis[i] = 1;dfs(num + 1);vis[i] = 0;}}}
}
int main()
{cin >> n;for(int i = 1; i <= n; i++) a[i] = i;dfs(0);return 0;
}
P1088 [NOIP2004 普及组] 火星人
#include
using namespace std;// 全排列
int n, m, a[10005], vis[10005], f1, f2;
void dfs(int num){if(f2 == 1) return;if(num > n){f1++ ;if(f1 == m + 1){for(int i = 1; i < num; i++)cout << a[i] << " ";cout << endl;f2 = 1;}}for(int i = 1; i <= n; i++){if(! f1) i = a[num];if(! vis[i]){a[num] = i, vis[i] = 1;dfs(num + 1);vis[i] = 0;}}
}
int main()
{cin >> n >> m;for(int i = 1; i <= n; i++) cin >> a[i];dfs(1);return 0;
}
计算序列全排列的函数:next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列
#include
using namespace std;
int main(){int n,m;cin>>n>>m;int ord[n+1];for(int i=1;i<=n;++i) cin>>ord[i];for(int i=1;i<=m;++i) next_permutation(ord+1,ord+1+n);for(int i=1;i