洛谷有感!!!!!
【题目信息】P1047 [NOIP 2005 普及组] 校门外的树
【知识点】数组初始化错误
bool tree[10000] = {true}; // ❌ 这只会初始化tree[0]=true,其他都是false!bool tree[10001]; // 0到l,需要l+1个位置 for (int i = 0; i <= 10000; i++) { tree[i] = true; // 所有树初始都在 }【易错点】变量名冲突+数组大小要足够
for(int i=0;i<m;i++){ // 外层循环用i for(int i=u;i<=v;i++){ // 内层循环也用i,会覆盖外层的i! tree[i]=false; } }数组大小要足够:包含0到l,需要l+1个元素
【代码】
#include<iostream> using namespace std; int main(){ int l,m; cin>>l>>m; int count_=0; bool tree[10001]; // 0到l,需要l+1个位置 for (int i = 0; i <= 10000; i++) { tree[i] = true; // 所有树初始都在 } for(int i=0;i<m;i++){ int u,v; cin>>u>>v; for(int j=u;j<=v;j++){ tree[j]=false; } } for(int i=0;i<=l;i++){ if(tree[i]){count_++;} } cout<<count_; return 0;}【题目信息】P1161开灯问题
【新知识点】
首先一个物品有两种状态首先去考虑bool类型 取反直接加一个感叹号
【易错点】
对于正数来说,int(a*i)就是a*i的整数部分(去掉小数部分)。等价于向下取整
floor(x):不超过x的最大整数
floor(3.7) = 3floor(3.0) = 3floor(-3.7) = -4(因为-4 ≤ -3.7 < -3)floor(-3.0) = -3
【代码】
#include <bits/stdc++.h> using namespace std; #define in cin #define out cout const int N = 1e6 + 5; bool flag[N]; //序列,由于只存在0和1,所以用bool节省空间 int main() { int n; in >> n; while (n--) { //n次询问 double a; int t; in >> a >> t; for (int i = 1; i <= t; i++) //模拟 flag[int(i * a)] = !flag[int(i * a)]; //取反 } for (int i = 0; i < N; i++) //遍历flag序列 if (flag[i]) { //如果flag[i]是true值,相当于当前状态为开灯 out << i; //输出答案 return 0; //结束 } }【题目信息】P1317低洼池
【知识点】关于左右两边坐标的数值相等的时候 很难判断出低洼
那就先把左坡找到 如果没有右坡 就一直向后面遍历 直到遍历到最后一个位置上
【易错点】
首先 除了题目这种持平的情况比较难解决
还有就是左坡虽然下降了 但是我们要找到下降的最低点 可能往后面几个才是最低点
左坡应该是要严格下降 如果可以有持平 那这个坡都不能开始 那么如果跳跃连续的低洼点呢 我们只需找到里面的最低点
if(arr[i] < arr[i-1]) { // 修正2: 用<不是<=
// 找洼地最低点(可能连续)
int lowest = i;//最低点的坐标+1开始不断更新
while(lowest+1 < n && arr[lowest+1] <= arr[lowest]) {
lowest++;
}
【代码】
#include<iostream> #include<vector> using namespace std; int main() { int n; cin >> n; vector<int> arr; for(int i = 0; i < n; i++) { // 从0开始 int h; cin >> h; arr.push_back(h); } int count_ = 0; for(int i = 1; i < n; i++) { // 修正1: i<n // 找到左坡:严格下降 if(arr[i] < arr[i-1]) { // 修正2: 用<不是<= // 找洼地最低点(可能连续) int lowest = i; while(lowest+1 < n && arr[lowest+1] <= arr[lowest]) { lowest++; } // 找右坡 bool found = false; for(int j = lowest+1; j < n; j++) { if(arr[j] > arr[lowest]) { // 修正3: 和最低点比较 count_++; i = j; // 修正4: 跳到右坡前一个位置 found = true; break; } } } } cout << count_ << endl; return 0; }【题目信息】压缩技术
【新知识】
首先题目都说了第一位输入的就是N 你为什么非要把N的这个位置放到数组上 可以分开输入的
其次你对于这题 不知道他要输入多少个数 这个时候也不知道是不是要用动态数组
这里也运用到了在输入数组的时候 偶数位输入的是0 奇数位输入的是1 记住是位而不是你输入的数字!!!!!
【易错】
最后的关于输出换行 犯了很久的错误
因为数组是从0开始存储的 所以每N个换一次行 但下标是从0开始的 我认为从i%(n-1)换行足以
因为二维数组每输出一行就会将j初始化为0 而此处不是!!!!!!!!!
但是我没有意识到这里是一维数组 要把它变成二维数组的形式进行输出 !!!!!!!!
所以应该用(i+1)%n取余 才仍然是每n个换一次行
其次 关于初始化
int arr[4000]={0}确实初始化为0了
但是bool arr[1000]={true;}//不是全部都初始化真了 往往只有代表的0才会真正全部初始化 你要全部初始化为真 就要通过循环 一个个初始化!!!!!!
【代码】
#include<iostream> using namespace std; int arr[40000]; int main(){ int N; cin>>N; int index=0; int x,cnt=1; while(cin>>x){ if(cnt%2!=0){index+=x;}//不用管输入的是0 但是下标记得往后面移 else{ for(int i=0;i<x;i++){ arr[index++]=1; } } cnt++; } for(int i=0;i<N*N;i++){ cout<<arr[i]; if((i+1)%N==0){ cout<<endl; } } return 0;}