点这里
A题 构造数列
这题么是很简单的,签到题,但是我好像想复杂了,罚时太长了,直接取出每一位不为零的数即可。
比赛时的做法
属实是个铁憨憨
#include <iostream>
#include <cstring>
#include <algorithm>
#include<vector>
using namespace std;
int n;
int a[28]={10000,9000,8000,7000,6000,5000,4000,3000,2000,1000,900,800,700,600,500,400,300,200,100,
90,80,70,60,50,40,30,20,10};
int main() {
int T;
cin >> T;
while (T--) {
vector<int> num;
cin >> n;
for (int i = 0; i <28 ; i++) {
if (a[i] <= n) {
n -= a[i];
num.push_back(a[i]);
}
if (n < 10 && n > 0) {
num.push_back(n);
break;
}
}
cout << num.size() << endl;
for (auto i: num)cout << i << ' ';
cout << endl;
}
return 0;
}
快的做法
#include <iostream>
#include <cstring>
#include <algorithm>
#include<vector>
using namespace std;
const int N = 10010;
int main()
{
int T;
cin>>T;
while(T--){
string str;
cin>>str;
vector<int> s;
for(int i=str.size()-1,j=1;i>=0;i--,j*=10){
if(str[i]!='0')
s.push_back((str[i]-'0')*j);
}
cout<<s.size()<<endl;
for(auto i:s)cout<<i<<' ';
cout<<endl;
}
return 0;
}
B题 浇花
本题的根本就是差分,但是因为数据的原因,暴力也可以过。
暴力做法
#include <iostream>
#include <cstring>
#include <algorithm>
#include<map>
#define f first
#define s second
using namespace std;
const int N = 100010;
int n,m;
map<int,int> mp;
int a[N];
int main() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
int l, r;
cin >> l >> r;
if (l == r)a[l]++;
else for(int j=l;j<=r;j++)a[j]++;
}
//for(int i=1;i<=n;i++)cout<<a[i]<<' ';cout<<endl;
for(int i=1;i<=n;i++){
if(a[i]==0||a[i]>1){
cout<<i<<' '<<a[i]<<endl;
return 0;
}
}
cout << "OK" << endl;
}
用差分来做
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n,m;
int b[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++){
int l,r;
cin>>l>>r;
b[l]++,b[r+1]--;
}
for(int i=1;i<=n;i++){
b[i]+=b[i-1];
if(b[i]>1||b[i]==0){
cout<<i<<' '<<b[i]<<endl;
return 0;
}
}
puts("OK");
return 0;
}
C题 构造新矩阵
这个题其实考察的是二分,给一个m乘以n的矩阵,让你输出一个尽可能大的值L使得最多选n-1行构造一个新矩阵,让这个新矩阵每一列至少有一个元素大于等与于L,因为L这个答案具有二段性,小于L的肯定成立,而大于L的肯定不成立,所以二分这个答案,然后我们就全部遍历一下这个矩阵,看看每一列是不是至少有一个数大于等于L,但只能取n-1行,所以我们还要再开一个数组取判断有没有至少两行的值大于等于L重复,只要有一个重复的就可以取n-1行否则就不行。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
vector<int> g[N];
int n, m;
bool st[N];
bool check(int x) {
memset(st, false, sizeof st);
bool same = false;
for (int i = 0; i < n; i++) {
bool success = false;
for (int j = 0; j < m; j++) {
if (g[j][i] >= x) {
success = true;
if (st[j])same = true;
st[j] = true;
}
}
if (!success)return false;
}
return same;
}
int main() {
int T;
cin >> T;
while (T--) {
cin >> m >> n;
for (int i = 0; i < m; i++) {
g[i].resize(n);
for (int j = 0; j < n; j++)
cin >> g[i][j];
}
int l = 1, r = 1e9;
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid))l = mid;
else r = mid - 1;
}
cout << l << endl;
}
return 0;
}