交换瓶子——贪心
分析:
最简单的思路就是暴力法,由于数据量较小,所以n^2不会超时。 具体做法为:贪心,每一次把不在该位置上的瓶子交换到正确的位置上。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int a[10005];
int main(){
int N;
cin>>N;
//最简单的思路,暴力法,由于数据量较小,所以n^2不会超时。
//贪心,每一次吧该瓶子交换到对的位置上。
for(int i = 1;i <= N ; ++i) cin>>a[i];
int ans = 0;
for(int i = 1; i <= N; ++i){
int flag = 1; //记录有没有不在位置上的。
for(int j = 1; j <= N; ++j)
if(a[j] != j){
swap(a[j],a[a[j]]);
ans++;
flag = 0;
}
if(flag) break; //提前结束
}
cout<<ans;
return 0;
}
四平方和
分析:
枚举,三重循环搞定!!!注意找到答案后退出循环,防止超时。
AC代码:
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int n;
cin>>n;
int flag = 1;
int l;
for(int i = 0; i*i <= n && flag; ++i){
for(int j = i; j*j + i*i <= n && flag; ++j){
for(int k = j ; j*j + i*i + k*k <= n && flag ; ++k){
l = sqrt(n - j*j - i*i - k*k);
//保证是开根号结果为整数。
if(l*l == n - j*j - i*i - k*k){
cout<<i<<" "<<j<<" "<<k<<" "<<l;
flag = 0;
}
}
}
}
}
路径之谜——dfs
分析:
dfs暴搜,搜索出所有的到达终点的方案,记录每一个到达终点的方案过程中的射箭到对应靶子的数量,看是否与题目要求的数量一致,若一致就输出结果。
额外注意的就是要剪枝,否则超时。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int bei[23]; //存放目标北方靶子
int xi[23]; //存放目标数量的西方靶子
int n;
int m[23][23]; //标记城堡位置
int flag[23][23]; // 记录有没有访问过。
int north[23]; //求出来的 北方靶子 上的箭头数量
int west[23]; //出来的 西方靶子 上的箭头数量
vector<int> path; //存放路径
void dfs(int i, int j){
if(i == n - 1 && j == n-1){
//最后一个位置要 的箭头 要 +上去
north[j]++;
west[i]++;
path.push_back(m[i][j]);
int flag1 = 1, flag2 = 1;
for(int k = 0; k < n ; ++k){
// cout<<north[k]<<" ";
if(bei[k] != north[k]){ //判断是否全部相等
flag1 = 0; break;
}
}
// cout<<endl;
for(int k = 0; k< n ; ++k){
// cout<<west[k]<<" ";
if(west[k] != xi[k]){ //判断是否全部相等
flag2 = 0; break;
}
}
// cout<<endl;
if(flag1 && flag2){ //都一样就输出结果
for(int k = 0; k < path.size(); ++k) cout<<path[k]<<" "; return;
}
//再回溯
north[j]--;
west[i]--;
path.pop_back();
}else{
//剪枝,如果加上该位置的射箭数量超过了目标数量就return。
if(north[j] + 1 > bei[j] || west[i] + 1 > xi[i]) return;
north[j]++;
west[i]++;
path.push_back(m[i][j]);
if(i + 1 < n && !flag[i+1][j]){ //走下方
flag[i+1][j] = 1;
dfs(i+1,j);
flag[i+1][j] = 0;
}
if(j + 1 < n && !flag[i][j+1]){ //走右方
flag[i][j+1] = 1;
dfs(i,j+1);
flag[i][j+1] = 0;
}
if(i-1 >= 0 && !flag[i-1][j]){ //走上方
flag[i-1][j] = 1;
dfs(i-1,j);
flag[i-1][j] = 0;
}
if(j-1 >= 0 && !flag[i][j-1]){ //走左方
flag[i][j-1] = 1;
dfs(i,j-1);
flag[i][j-1] = 0;
}
//回溯
north[j]--;
west[i]--;
path.pop_back();
}
}
int main(){
cin>>n;
for(int i = 0; i< n ; ++i){
cin>>bei[i];
}
for(int i =0 ; i < n ; ++i) cin>>xi[i];
//初始化 城堡
for(int i = 0; i < n ; ++i){
for(int j = 0; j < n ; ++j){
m[i][j] = i * n + j;
}
}
flag[0][0] = 1; //初始化
dfs(0 , 0);
return 0;
}
刻苦学习了一天!好充实!好幸福!