目录
[P1003 [NOIP 2011 提高组] 铺地毯](#P1003 [NOIP 2011 提高组] 铺地毯)
[P1067 [NOIP 2009 普及组] 多项式输出](#P1067 [NOIP 2009 普及组] 多项式输出)
[P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布](#P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布)
[P1563 [NOIP 2016 提高组] 玩具谜题](#P1563 [NOIP 2016 提高组] 玩具谜题)
[P1042 [NOIP 2003 普及组] 乒乓球](#P1042 [NOIP 2003 普及组] 乒乓球)
[P1179 [NOIP 2010 普及组] 数字统计](#P1179 [NOIP 2010 普及组] 数字统计)
[P2615 [NOIP 2015 提高组] 神奇的幻方](#P2615 [NOIP 2015 提高组] 神奇的幻方)
[P3952 [NOIP 2017 提高组] 时间复杂度](#P3952 [NOIP 2017 提高组] 时间复杂度)
[P2482 [SDOI2010] 猪国杀](#P2482 [SDOI2010] 猪国杀)
[P5380 [THUPC 2019] 鸭棋](#P5380 [THUPC 2019] 鸭棋)
P1003 [NOIP 2011 提高组] 铺地毯
一开始用很大的数组存储所有地毯的信息,时间和空间太大了,最后MLE
可以换一种思路:把信息存储起来,先读入要找的坐标,确认坐标后,再挨个找之前存储的地毯中覆盖该坐标的地毯的编号
cpp
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n;
cin>>n;
vector<vector<int>> s(n,vector<int>(4));
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<4;j++){
cin>>s[i][j];
}
}
cin>>x>>y;
int ans=-1;
for(int i=0;i<n;i++){
int x_left_bottom=s[i][0];
int y_left_bottom=s[i][1];
int x_right_top=s[i][0]+s[i][2];
int y_right_top=s[i][1]+s[i][3];
if(x>=x_left_bottom&&x<=x_right_top&&y>=y_left_bottom&&y<=y_right_top)ans=i+1;
}
cout<<ans;
return 0;
}
P1067 [NOIP 2009 普及组] 多项式输出
有很多坑
1、x的次数,如果是1,那么"^1"是不用写的
2、如果数字1在x前面,不用写,如果是常数,要写
3、注意转化方法
int转string:to_string();
string转int:stoi();
用s存储答案,是因为考虑到了输入全是0的情况,可惜后来发现题目中明确说明不能全是0,所以写了也没啥用了
注意读题!!!
cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n;
cin >> n;
string s = "";
for (int i = 0; i <= n; i++)
{
int t;
cin >> t;
if (t > 0)
{
if (i != 0)s += '+';
if (n - i != 0)
{
if (t != 1)s += to_string(t);
s += 'x';
if (n - i != 1)
{
s += '^';
s += to_string(n - i);
}
}
else s += to_string(t);
}
else if (t < 0)
{
s += '-';
if (n - i != 0)
{
if (t != -1)s += to_string(-t);
s += 'x';
if (n - i != 1)
{
s += '^';
s += to_string(n - i);
}
}
else s += to_string(-t);
}
}
if (s.size() == 0)cout << 0;
else cout << s;
return 0;
}
P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布
匹配很复杂,一开始画了一张图对应,分情况讨论
后来发现可以存二维数组(把结果存进去)
cpp
#include <iostream>
#include <vector>
using namespace std;
vector<int> a, b;
int n;
int A, B;
int scoreA, scoreB;
void solve(int x, int y)
{
if (x == y)
return;
if (x == 0)
{
if (y == 2 || y == 3)
{
scoreA++;
return;
}
}
else if (x == 1)
{
if (y == 0 || y == 3)
{
scoreA++;
return;
}
}
else if (x == 2)
{
if (y == 1 || y == 4)
{
scoreA++;
return;
}
}
else if (x == 3)
{
if (y == 2 || y == 4)
{
scoreA++;
return;
}
}
else if (x == 4)
{
if (y == 0 || y == 1)
{
scoreA++;
return;
}
}
scoreB++;
}
int main()
{
cin >> n >> A >> B;
a.resize(A);
b.resize(B);
for (int i = 0; i < A; i++)
{
cin >> a[i];
}
for (int i = 0; i < B; i++)
{
cin >> b[i];
}
int pA = 0;
int pB = 0;
while (n--)
{
solve(a[pA], b[pB]);
pA++;
pB++;
if (pA == A)
pA = 0;
if (pB == B)
pB = 0;
}
cout << scoreA << " " << scoreB;
return 0;
}
优化:
注意vector初始化方法
cpp
#include <iostream>
#include <vector>
using namespace std;
int x, y;
int main()
{
int n, a, b;
cin >> n >> a >> b;
vector<int> A(a);
vector<int> B(b);
for (int i = 0; i < a; i++)
{
cin >> A[i];
}
for (int i = 0; i < b; i++)
{
cin >> B[i];
}
vector<vector<int>> gra = {{0, 0, 1, 1, 0},
{1, 0, 0, 1, 0},
{0, 1, 0, 0, 1},
{0, 0, 1, 0, 1},
{1, 1, 0, 0, 0}};
for (int i = 0; i < n; i++)
{
x += gra[A[i % a]][B[i % b]];
y += gra[B[i % b]][A[i % a]];
}
cout << x << " " << y;
return 0;
}
P1563 [NOIP 2016 提高组] 玩具谜题
两个数字,不同时向右走,相同时向左走
注意向左走时可能是负数,代码可以写成p = (p % n + n) % n;
原来用一个二维string数组存数据,卡了很久,其实可以用两个数组来存
cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
vector<vector<string>> s(n, vector<string>(2));
for (int i = 0; i < n; i++)
{
cin >> s[i][0] >> s[i][1];
}
int a, k;
int p = 0;
while (m--)
{
cin >> a >> k;
k %= n;
if ((s[p][0] == "1" && a == 0) || (s[p][0] == "0" && a == 1))
{
p += k;
}
else
{
p -= k;
}
p = (p % n + n) % n;
}
cout << s[p][1];
return 0;
}
优化:
cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
vector<int> num(n);
vector<string> job(n);
for (int i = 0; i < n; i++)
{
cin >> num[i] >> job[i];
}
int a, k;
int p = 0;
while (m--)
{
cin >> a >> k;
k %= n;
if (num[p] == a)
{
p -= k;
}
else
{
p += k;
}
p = (p % n + n) % n;
}
cout << job[p];
return 0;
}
P1042 [NOIP 2003 普及组] 乒乓球
这道题目看起来有点怪
1、题目中并没有明确说胜利条件是当有一方分数>=11且比对方高>=2分时。举的例子也是11:0、21:0之类的,我误以为只要进行11局或21局,最后得分高者胜利。
2、注意:当一局比赛结束后,下一局立刻开始。这句话我没理解是什么意思。
题目想提醒的应该是最后当x和y都是0时也要输出(写了同时是0的判断条件后WA了好多),但是我没理解这行代码跟题目的提醒有什么关系。
不知道是我的理解能力差,还是题目真的有点误导人?
如果题目改一下描述思路就会清楚很多
cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
char t;
vector<int> s;
while (cin >> t)
{
if (t == 'E')
{
break;
}
if (t == 'W')
{
s.push_back(1);
}
else
{
s.push_back(0);
}
}
int x = 0;
int y = 0;
for (int i : s)
{
if (i)
{
x++;
}
else
{
y++;
}
if (max(x, y) >= 11 && abs(x - y) >= 2)
{
cout << x << ":" << y << endl;
x = 0;
y = 0;
}
}
cout << x << ":" << y << endl;
x = 0;
y = 0;
cout << endl;
for (int i : s)
{
if (i)
{
x++;
}
else
{
y++;
}
if (max(x, y) >= 21 && abs(x - y) >= 2)
{
cout << x << ":" << y << endl;
x = 0;
y = 0;
}
}
cout << x << ":" << y << endl;
return 0;
}
P1179 [NOIP 2010 普及组] 数字统计
left和right不能写在全局变量中
在 C++ 标准库里(以及某些编译器/IDE 预编译头里),有一些东西叫
std::left/std::right------它们是 iostream 的"对齐格式控制器"(比如cout << left << setw(10)这种)。当你写了:
using namespace std; int left, right;你的全局变量名
left/right会和std::left/std::right发生冲突。IDE 的语义检查器(尤其是 VSCode 的 IntelliSense / clangd)就可能报:
"left" 不明确/"right" 不明确因为它看到
left时,不确定你指的是全局变量还是std::left操纵符。
cpp
#include <iostream>
using namespace std;
int ans;
int L, R;
int main()
{
cin >> L >> R;
for (int i = L; i <= R; i++)
{
int t = i;
while (t)
{
if (t % 10 == 2)
{
ans++;
}
t /= 10;
}
}
cout << ans;
return 0;
}
P2615 [NOIP 2015 提高组] 神奇的幻方
很简单的模拟,按照题意写即可
cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<vector<int>> s(n, vector<int>(n));
s[0][n / 2] = 1;
int x = 0;
int y = n / 2;
for (int k = 2; k <= n * n; k++)
{
if (x == 0 && y != n - 1)
{
x = n - 1;
y = y + 1;
}
else if (y == n - 1 && x != 0)
{
y = 0;
x = x - 1;
}
else if (x == 0 && y == n - 1)
{
x = x + 1;
}
else if (x != 0 && y != n - 1)
{
if (s[x - 1][y + 1] == 0)
{
x = x - 1;
y = y + 1;
}
else
{
x = x + 1;
}
}
s[x][y] = k;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << s[i][j] << " ";
}
cout << endl;
}
return 0;
}
P3952 [NOIP 2017 提高组] 时间复杂度
用栈模拟
好难的模拟题
P2482 [SDOI2010] 猪国杀
P5380 [THUPC 2019] 鸭棋
