小鱼比可爱
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int>arr(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int count = 0;
cout << "0" << " ";
for (int i = 1; i < n; i++) {
for (int j = i - 1; j >= 0; j--) {
if (arr[i] > arr[j])count++;
}
cout << count << " ";
count = 0;
}
return 0;
}
小鱼的数字游戏
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int>arr;
int x;
cin >> x;
while (x) {
arr.push_back(x);
cin >> x;
}
for (int i = arr.size() - 1; i >= 0; i--) {
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
【深基5.例3】冰雹猜想
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int>arr;
arr.push_back(n);
while (n != 1) {
if (n % 2 == 0) {
n /= 2;
arr.push_back(n);
}
else {
n = 3 * n + 1;
arr.push_back(n);
}
}
for (int i = arr.size()-1; i >= 0; i--) {
cout << arr[i] << " ";
}
return 0;
}
[NOIP2005 普及组] 校门外的树
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int l, m;
cin >> l >> m;
vector<bool>trees(l + 1, true);
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
for (int j = u; j <= v; j++) {
if (j >= 0 && j <= l) {
trees[j] = false;
}
}
}
int remainTrees = 0;
for (int i = 0; i < l + 1; i++) {
if (trees[i])remainTrees++;
}
cout << remainTrees << endl;
return 0;
}
注意:
像这种,有重合部分,而且如果分情况讨论的话,比较复杂多样,比如说这道题,需要判断第二次输入的u2是不是比上一个v1要小,是否相等,又或者比它大;如果是比较小,还要再判断v2是否也小于v1……
所以可以直接使用一个布尔向量,把所有在范围内的Tree都标记为false,同时只需要判断每一个点是否在有效范围内即可。
【深基5.例5】旗鼓相当的对手
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
int sum1, sum2, count = 0;
vector<vector<int>>score(n, vector<int>(3));
for (int i = 0; i < n; i++) {
cin >> score[i][0] >> score[i][1] >> score[i][2];
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
sum1 = score[i][0] + score[i][1] + score[i][2];
sum2 = score[j][0] + score[j][1] + score[j][2];
int x = score[i][0] - score[j][0];
int y = score[i][1] - score[j][1];
int z = score[i][2] - score[j][2];
if (abs(sum1 - sum2)<=10 &&
abs(x)<=5 &&
abs(y)<=5 &&
abs(z)<=5) {
count++;
}
}
}
cout << count << endl;
return 0;
}
【深基5.例7】工艺品制作
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
int w, x, h;
cin >> w >> x >> h;
int q;
cin >> q;
int arr[20][20][20] = { 0 };
while (q--) {
int x1, y1, z1, x2, y2, z2;
cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
for (int i = x1 - 1; i < x2;i++ ){
for (int j = y1 - 1; j < y2; j++) {
for (int k = z1 - 1; k < z2; k++) {
arr[i][j][k] = 1;
}
}
}
}
int count = 0;
for (int i = 0; i < w; i++) {
for (int j = 0; j < x; j++) {
for (int k = 0; k < h; k++) {
if (arr[i][j][k]==0) {
count++;
}
}
}
}
cout << count << endl;
return 0;
}
[AHOI2001] 彩票摇奖
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
int a[7];
vector<int>vec;
for (int i = 0; i < 7; i++) {
cin >> a[i];
}
int count = 0;
for(int k=0;k<n;k++) {
int x1, x2, x3, x4, x5, x6, x7;
cin >> x1 >> x2 >> x3 >> x4 >> x5 >> x6 >> x7;
for (int i = 0; i < 7; i++) {
if (x1 == a[i])count++;
if (x2 == a[i])count++;
if (x3 == a[i])count++;
if (x4 == a[i])count++;
if (x5 == a[i])count++;
if (x6 == a[i])count++;
if (x7 == a[i])count++;
}
vec.push_back(count);
count = 0;
}
for (int i = 7; i>0; i--) {
for (int j = 0; j < n; j++) {
if (vec[j] == i)count++;
}
cout << count << " ";
count = 0;
}
return 0;
}
注意:
for(int k=0;k<n;k++)这一步不能用while(n--)来循环,因为这样的话,n会减少到0,等到后面需要判断vec[j]是否==i的时候,不会进入这个循环
整体思路:先用一个a[7]固定数组存放中奖号码,注意,只要有一样的数字就算有中奖号码,而不一定要一一对应。然后循环n次,找出每个彩票里面的中奖号码数,将其存放到vec数组中。最后只需要判断7~1个中奖号码的数量输出即可
[NOIP2015 提高组] 神奇的幻方
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
vector<vector<int>>vec(n, vector<int>(n));
vec[0][n/2] = 1;
int r = 0, c =n/2;
for (int i = 2; i <= n * n; i++) {
if (r == 0 && c != n - 1) {
vec[n - 1][c + 1] = i;
r = n - 1, c += 1;
}
else if (c == n - 1 && r != 0) {
vec[r - 1][0] = i;
r -= 1, c = 0;
}
else if (r == 0 && c == n - 1) {
vec[r + 1][c] = i;
r += 1;
}
else if (r != 0 && c != n - 1) {
if (vec[r - 1][c + 1] == 0
&& r-1>=0 && c+1<n) {
vec[r - 1][c + 1] = i;
r -= 1, c += 1;
}
else {
vec[r + 1][c] = i;
r += 1;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << vec[i][j] << " ";
}
cout << endl;
}
return 0;
}
注意:
这道题我采用的是纯模拟,就是直接照着题目要求模拟就行,但是由于题目要求有点多,大家注意不要看差行了。
【深基5.例10】显示屏
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
string ans[10];
for (int i = 1; i <= n; i++) {
char x;
cin >> x;
if (x == '1')
{
ans[1] += "..X.";
ans[2] += "..X.";
ans[3] += "..X.";
ans[4] += "..X.";
ans[5] += "..X.";
}
if (x == '2')
{
ans[1] += "XXX.";
ans[2] += "..X.";
ans[3] += "XXX.";
ans[4] += "X...";
ans[5] += "XXX.";
}
if (x == '3')
{
ans[1] += "XXX.";
ans[2] += "..X.";
ans[3] += "XXX.";
ans[4] += "..X.";
ans[5] += "XXX.";
}
if (x == '4')
{
ans[1] += "X.X.";
ans[2] += "X.X.";
ans[3] += "XXX.";
ans[4] += "..X.";
ans[5] += "..X.";
}
if (x == '5')
{
ans[1] += "XXX.";
ans[2] += "X...";
ans[3] += "XXX.";
ans[4] += "..X.";
ans[5] += "XXX.";
}
if (x == '6')
{
ans[1] += "XXX.";
ans[2] += "X...";
ans[3] += "XXX.";
ans[4] += "X.X.";
ans[5] += "XXX.";
}
if (x == '7')
{
ans[1] += "XXX.";
ans[2] += "..X.";
ans[3] += "..X.";
ans[4] += "..X.";
ans[5] += "..X.";
}
if (x == '8')
{
ans[1] += "XXX.";
ans[2] += "X.X.";
ans[3] += "XXX.";
ans[4] += "X.X.";
ans[5] += "XXX.";
}
if (x == '9')
{
ans[1] += "XXX.";
ans[2] += "X.X.";
ans[3] += "XXX.";
ans[4] += "..X.";
ans[5] += "XXX.";
}
if (x == '0')
{
ans[1] += "XXX.";
ans[2] += "X.X.";
ans[3] += "X.X.";
ans[4] += "X.X.";
ans[5] += "XXX.";
}
}
for (int i = 1; i <= 5; i++) {
ans[i] = ans[i].substr(0, ans[i].length()-1);
cout << ans[i] << endl;
}
return 0;
}
注意:
这道题的话,感觉也没什么含金量(bushi),就是把依据输入的数字,一行一行的添加到String ans[10](注意不是ans[5]这样的结果是错误的,因为我是从下标为1开始的,其实也可以设置为ans[6])中。其次,就是ans[i] = ans[i].substr(0, ans[i].length()-1);注意是length-1,不是length
没必要用二维数组,感觉用二维数组反而麻烦
梦中的统计
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
int m, n;
cin >> m >> n;
int arr[10] = { 0 };
for (int i = m; i <= n; i++) {
string s = to_string(i);
for (int j = 0; j < s.length(); j++) {
arr[s[j]-'0']++;
}
}
for (int i = 0; i < 10; i++) {
cout << arr[i] << " ";
}
return 0;
}
注意:
for循环嵌套时,一定要注意不能使用一样的变量名,我一开始习惯性全部设为i了,直接unaccept,泪目;还有就是没必要用很多if或者switch去判断每个s[j],直接用s[j]-'0'就OK了,泪目,血的教训。上一道题“显示屏”我暂时没想到如果不用if或者switch的话还能用什么。
[NOIP2014 普及组] 珠心算测验
#include <iostream>
#include <unordered_set>
using namespace std;
const int M = 2e4 + 1;
int vis[M], a[102];
int n, ans;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
vis[a[i]] = 1;
}
unordered_set<int>set;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
int sum = a[i] + a[j];
if (vis[sum] == 1 &&
a[i] != a[j] ) {
set.insert(sum);
}
}
}
for (int x : set) {
ans++;
}
cout << ans << endl;
return 0;
}
注意:
ans不应该在set每次insert的时候++,因为有可能有重复的
爱与愁的心痛
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int minn = 3e5 + 1;
int n, m;
cin >> n >> m;
vector<int>vec(n);
for (int i = 0; i < n; i++) {
cin >> vec[i];
}
if (n == m) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += vec[i];
}
cout << sum << endl;
return 0;
}
for (int i = 0; i < n - m; i++) {
int sum = 0;
for (int j = i; j < i + m; j++) {
sum += vec[j];
}
if (sum < minn)minn = sum;
}
cout << minn << endl;
return 0;
}
注意:
这道题有两个坑点:
1,那个minn=3e5+1,不是3e3+1,我一开始直接按照m,n的最大值来设置的,结果ai<=100,还要再乘100,泪目
2,n==m的时候要单独判断
[USACO08OCT] Bovine Bones G
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int>pos(81);
int a[4];
for (int i = 1; i <= 3; i++)cin >> a[i];
//按照筛子大小排序
if (a[1] > a[2])swap(a[1], a[2]);
if (a[2] > a[3])swap(a[2], a[3]);
if (a[1] > a[2])swap(a[1], a[2]);
//cout << a[1] << a[2] << a[3];
for (int i = 1; i <= a[1]; i++) {
for (int j = 1; j <= a[2]; j++) {
for (int k = 1; k <= a[3]; k++) {
int sum = i + j + k;
pos[sum]++;
}
}
}
int max_count = 0;
int ans = 0;
for (int i = 3; i < a[1] + a[2] + a[3]; i++) {
if (pos[i] > max_count) {
max_count = pos[i];
ans = i;
}
else if (pos[i] == max_count && i < ans) {
ans = i;
}
}
cout << ans << endl;
return 0;
}
注意:
最好定义两个变量,一个max_count用来记录pos[i],一个ans用来记录i,这样不会混,我一开始就是自己都搞混了
开灯
#include <iostream>
#include <vector>
using namespace std;
const int m = 2e6 + 1;
int main()
{
int n;
cin >> n;
vector<bool>vec(m,false);
for (int i = 0; i < n; i++) {
double a;
int t;
cin >> a >> t;
for (int j = 1; j <= t; j++) {
if (vec[int(j * a)])vec[int(j * a)] = false;
else vec[int(j * a)] = true;
}
}
int count = 0;
for (int i = 0; i < m; i++) {
if (vec[i]) {
cout << i << endl;
break;
}
}
return 0;
}
【深基5.习6】蛇形方阵
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<vector<int>>vec(n, vector<int>(n));
int startX = 0, startY = 0;
int endX = n - 1, endY = n - 1;
int loop = n / 2;
int count = 1;
while (loop--) {
for (int j = startY; j < endY; j++) {
vec[startX][j] = count++;
}
for (int i = startX; i < endX; i++) {
vec[i][endY] = count++;
}
for (int j = endY; j > startY; j--) {
vec[endX][j] = count++;
}
for (int i = endX; i > startX; i--) {
vec[i][startY] = count++;
}
startX++;
startY++;
endY--;
endX--;
}
if (n % 2 == 1)vec[n / 2 ][n / 2 ] = count;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%3d", vec[i][j]);
}
cout << endl;
}
return 0;
}
注意:
如果是奇数的话,应该把vec[n/2][n/2]的位置填充为count,注意不是n/2+1,因为数组下标从0开始
【深基5.习7】杨辉三角
#include <iostream>
using namespace std;
int a[20][20];
int main()
{
int n;
cin >> n;
a[0][0] = 1;
for (int i = 1; i < 20; i++) {
a[i][0] = 1;
a[i][i] = 1;
}
for (int i = 2; i < 20; i++) {
for (int j = 1; j <= i; j++) {
a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
注意:
第二个for循环的嵌套循环中,j<=i,我一开始没注意写成了j<19,;还有输出的时候的i<n,j<=i
【Mc生存】插火把
#include <iostream>
using namespace std;
int a[102][102];
int main()
{
int n, m, k;
cin >> n >> m >> k;
while (m--) {
int x, y;
cin >> x >> y;
for (int i = x - 2; i <= x + 2; i++) {
if (i > 0 && i<101)a[i][y] = 1;
}
for (int j = y - 2; j <= y + 2; j++) {
if (j > 0 && j < 101)a[x][j] = 1;
}
if (x - 1 > 0 && y-1 > 0)a[x - 1][y - 1] = 1;
if (x - 1 > 0 && y + 1 < 101)a[x - 1][y + 1] = 1;
if (x + 1 < 101 && y - 1 > 0)a[x + 1][y - 1] = 1;
if (x + 1 < 101 && y + 1 < 101)a[x + 1][y + 1] = 1;
}
while (k--) {
int x, y;
cin >> x >> y;
for (int i = x - 2; i <= x + 2; i++) {
for (int j = y - 2; j <= y + 2; j++) {
if(i>0 && i<101 &&
j>0 && j<101)
a[i][j] = 1;
}
}
}
int count = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (a[i][j] == 0)count++;
}
}
cout<<count<<endl;
return 0;
}
压缩技术
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<vector<int>>vec(n, vector<int>(n));
int count = 0;
int right = 1;
int sum = 0;
while (sum!=n*n) {
int x;
cin >> x;
if (right>0) {
for (int i = 0; i < x; i++) {
if (count == n) {
cout << endl;
count = 0;
}
cout << "0";
count++;
}
}
else {
for (int i = 0; i < x; i++) {
if (count == n) {
cout << endl;
count = 0;
}
cout << "1";
count++;
}
}
right = -right;
sum += x;
}
return 0;
}
压缩技术(续集版)
#include <iostream>
using namespace std;
int main()
{
string a[201];
char c = '0';
int sum = 0;
cin >> a[0];
for (int i = 1; i < a[0].size(); i++) {
cin >> a[i];
}
cout << a[0].size() << " ";
for (int i = 0; i < a[0].size(); i++) {
for (int j = 0; j < a[0].size(); j++) {
if (a[i][j] == c)sum++;
else {
c = a[i][j];
cout << sum << " ";
sum = 0;
sum++;
}
}
}
cout << sum << endl;
return 0;
}
注意:
第一个for循环的初始值是i=1
[USACO1.2] 方块转换 Transformations
#include <iostream>
using namespace std;
char a[15][15], b[15][15], c[15][15], d[15][15];
int n;
bool rotate90()
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
b[j][n - i + 1] = a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (b[i][j] != c[i][j]) {
return false;
}
}
}
return true;
}
bool rotate180()
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
b[n - i + 1][n - j + 1] = a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (b[i][j] != c[i][j]) {
return false;
}
}
}
return true;
}
bool rotate270()
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
b[n - j + 1][i] = a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (b[i][j] != c[i][j]) {
return false;
}
}
}
return true;
}
bool reflect()
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
b[i][n - j + 1] = a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (b[i][j] != c[i][j]) {
return false;
}
}
}
return true;
}
bool mix()
{
reflect();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
a[i][j] = b[i][j];
}//更新数组a,因为经过了一次reflect函数
}
if (rotate90())return true;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
a[i][j] = b[i][j];
}
}
if (rotate180())return true;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
a[i][j] = b[i][j];
}
}
if (rotate270())return true;
return false;
}
bool same()
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (b[i][j] != c[i][j]) {
return false;
}
}
}
return true;
}
void solve()
{
if (rotate90()) {
cout << "1" << endl;
return;
}
if (rotate180()) {
cout << "2" << endl;
return;
}
if (rotate270()) {
cout << "3" << endl;
return;
}
if (reflect()) {
cout << "4" << endl;
return;
}
if (mix()) {
cout << "5" << endl;
return;
}
if (same()) {
cout << "6" << endl;
return;
}
cout << "7" << endl;
return;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
d[i][j] = a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> c[i][j];
}
}
solve();
return 0;
}
注意:
这个主要是要找到数组旋转后i,j的变化,还有就是mix函数中应该先更新完数组a之后再判断是否符合rotate90之类的函数,而不是在数组内部判断