1101 Quick Sort (25 分)
只要将数组排序后lower_bound二分查找到这个元素的位置是不是和排序前在同一个位置就能过3个测试点,然后要注意有9 8 7这种序列,前后大于和小于的数正好相等,所以还需要记录一下最大值即可
一个令人无语的测试点2,一直是格式错误,就是最后要多输出一遍换行,即空一行
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
vector<int> ans;
int arr[N], a[N], ma[N];
unordered_map<int, int>mp;
int main() {
int n;
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%d",a+i);
arr[i] = a[i];
ma[i] = max(ma[i-1], a[i]);
}
sort(arr, arr+n);
for(int i = 0; i < n; i++) {
int p = lower_bound(arr, arr+n, a[i]) - arr;
if(p == i && a[i] == ma[i]) ans.push_back(a[i]);
}
printf("%d\n",ans.size());
for(int i = 0; i < ans.size(); i++) {
if(i) printf(" ");
printf("%d",ans[i]);
}
printf("\n");
return 0;
}
/*
7
1 3 2 4 7 6 8
*/
1103 Integer Factorization (30 分)
带有多重剪枝的dfs,这些剪枝要记熟,有点类似切蛋糕的题,我觉得从大到小找应该比较快(其实题目也提示了应该找从大到小的序列比较好)
剪枝情况
- 元素不足k个但是p次方和已经比n要大了,直接返回
- 后面的k-num个元素(num为当前已有的元素个数)全部取最大值仍然比n小,直接结束
- 提前算好结果序列最大值可能的范围
#include<bits/stdc++.h>
using namespace std;
vector<int> ans, tem;
int n, k, p, s1, s2, low, high;
int ksm(int a, int b){
int ans = 1;
for(; b; b >>= 1) {
if(b&1) ans *= a;
a *= a;
}
return ans;
}
void dfs(int x, int sum, int num) {
if(num < k && sum > n) return;
if(num == k) {
if(sum == n && s2 > s1) {
ans = tem;
s1 = s2;
}
return;
}
for(int i = x; i >= 1; i--) {
int now = ksm(i, p) ;
if(sum + now*(k-num) < n) break;
tem.push_back(i);
s2 += i;
dfs(i, sum + now, num+1);
s2 -= i;
tem.pop_back();
}
}
int main() {
scanf("%d %d %d",&n,&k,&p);
high = pow(n, 1.0/p);
low = ceil(pow(n/k, 1.0/p));
for(int i = high; i >= low; i--) {
tem.push_back(i);
s2 += i;
dfs(i, ksm(i,p), 1);
s2 -= i;
tem.pop_back();
}
if(ans.size() == k) {
printf("%d =",n);
for(int i = 0; i < ans.size(); i++) {
if(i) printf(" +");
printf(" %d^%d",ans[i],p);
}
}
else printf("Impossible");
return 0;
}
1104 Sum of Number Segments (20 分)
这题我称之为不想让你拿满分型
只有一种形式能过,就是*1000,乘100, 10000通通都是错的,还有那个double到long long的强制类型转换一定要有,否则也会错
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main() {
ll n;
scanf("%lld",&n);
ll ans = 0;
double t;
for(ll i = 1; i <= n; i++ ) {
scanf("%lf",&t);
ans += (long long)(t * 1000) * i * (n + 1 - i);
}
printf("%.2f",ans/1000.0);
return 0;
}
1106 Lowest Price in Supply Chain (25 分)
和1079几乎完全相同,同样考虑只有根节点的情况;
如果考虑剪枝就记录结点深度,记录第一个出现的叶子结点的深度,如果访问到比这个叶子结点还深的结点,直接返回,但是不剪枝也能过。。。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
vector<int> v[N];
bool isr[N];
int num;
double price[N], r, mi = 0x3f3f3f3f;
void bfs() {
queue<int> q;
q.push(0);
while(q.size()) {
int x = q.front();
q.pop();
for(int i = 0; i < v[x].size(); i++) {
int y = v[x][i];
price[y] = price[x] * r;
if(isr[y]) {
if(mi > price[y]) mi = price[y], num = 1;
else if(mi == price[y]) num++;
}
else q.push(y);
}
}
}
int main() {
int n, k, id;
scanf("%d %lf %lf",&n, &price[0], &r);
r = 1 + r/100;
for(int i = 0; i < n; i++) {
scanf("%d",&k);
if(k) {
while(k--) {
scanf("%d",&id);
v[i].push_back(id);
}
}
else isr[i] = 1;
}
bfs();
if(n == 1) printf("%.4lf 1",price[0]);
else printf("%.4lf %d", mi, num);
return 0;
}
1107 Social Clusters (30 分)
一道有点点复杂的并查集,要记录每个根的大小,我采取的办法是初始化时把每个根赋值为1,然后每次合并时把被合并的大小加到合并的根上,并且把被合并的根大小置为0,因为这个节点被合并之后在也不会作为根出现了,这样就能找出最后最终的根及大小了
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
int n, fa[N], num, root[N];
vector<int> hob[N], siz;
set<int> hobby;
int find(int x) {
if(x == fa[x]) return x;
else return fa[x] = find(fa[x]);
}
void merge(int x, int y) {
return;
}
int main() {
scanf("%d",&n);
num = n;
for(int i = 1; i <= n; i++) {
fa[i] = i;
root[i] = 1;
}
for(int i = 1; i <= n; i++) {
int q, h;
scanf("%d:",&q);
while(q--) {
scanf("%d", &h);
hob[h].push_back(i);
hobby.insert(h);
}
}
for(auto it: hobby) {
for(int j = 0; j < hob[it].size()-1; j++) {
int x = hob[it][j], y = hob[it][j+1];
int fx = find(x), fy = find(y);
if(fx != fy) {
fa[fx] = fy;
root[fy] += root[fx];
root[fx] = 0;
num--;
}
}
}
cout<<num<<endl;
for(int i = 1;i <= n; i++) {
if(root[i]) siz.push_back(root[i]);
}
sort(siz.begin(), siz.end());
for(int i = siz.size()-1; i >= 0; i--) {
printf("%d",siz[i]);
if(i) printf(" ");
}
return 0;
}
1108 Finding Average (20 分)
测试点0应该就跟题目给的第一个输入样例一样,没什么特别的(10分)
测试点1跟题目给的第二个输入样例一样(5分)
测试点2就是输出要求的最后一句话,number不要用复数(2分)
测试点3给的小数点后有后置0(3分)
没认真审题,全部踩坑
#include<bits/stdc++.h>
using namespace std;
double s2i(string s) {
double n;
stringstream ss;
ss << s;
ss >> n;
return n;
}
bool islegal(string s) {
int l = s.length();
map<char, int> mp;
int p = s.find('.'), i;
if(s[0] == '-' || s[0] == '+') i = 1;
else i = 0;
for(; i < l; i++) {
if(s[i] == '.' ) {
if(mp.count('.') == 0) mp['.']++;
else return false;
}
else if(!isdigit(s[i])) return false;
}
for(i = l - 1; i > p; i--) {
if(s[i] != '0') break;
}
if(p != string::npos && i - p > 2) return false;
return true;
}
int main() {
int n;
cin >>n;
double total = 0;
int num = 0;
string s;
while(n--) {
cin >> s;
if(islegal(s) && s2i(s) >= -1000 && s2i(s) <= 1000) {
num++;
total += s2i(s);
}
else printf("ERROR: %s is not a legal number\n", s.c_str());
}
if(num > 1) printf("The average of %d numbers is %.2lf\n",num, total/num);
else if(num == 1) printf("The average of %d number is %.2lf\n",num, total/num);
else printf("The average of 0 numbers is Undefined\n");
return 0;
}
/*
7
5 -3.2 003.23 1000 2.3.4 7.123 2.35
*/
1109 Group Photo (25 分)
看清题目,一开始没搞清楚k是行数,以为每一行的人数
用双端队列,将每个人按身高名字排序后依次按照题意模拟加入每一行即可
#include<bits/stdc++.h>
using namespace std;
deque<int> q[10005];
struct node{
string name;
int h;
friend bool operator<(node a, node b) {
if(a.h == b.h) return a.name < b.name;
else return a.h > b.h;
}
}p[10005];
int main() {
int n, k;
scanf("%d %d", &n, &k);
for(int i = 0; i < n; i++) {
cin >> p[i].name >> p[i].h;
}
sort(p, p+n);
int num = n/k, rest = num + n % num, m = 0;
for(int i = 1; i <= rest; i++) {//最后一行单独处理一下
if(i % 2) q[k].push_back(m);
else q[k].push_front(m);
m++;
}
for(int i = k-1; i > 0; i--) {
for(int j = 1; j <= num; j++) {
if(j % 2) q[i].push_back(m);
else q[i].push_front(m);
m++;
}
}
for(int i = k; i >= 1; i--) {
int t = 0;
for(auto it: q[i]) {
if(t++) printf(" ");
cout<<p[it].name;
}
cout<<endl;
}
return 0;
}
1110 Complete Binary Tree (25 分)
完全二叉树的话,我一开始想的是把结点遍历一遍只要出现下标大于n,就会出错,但这样会最后一个测试点是错的;
必须记录最大小标,只要不等于n就是出错(所以可能给我的数据不是一棵树吗,否则不可能会出现最大下标小于n的情况吧,想不通。。。)
24分代码
#include<bits/stdc++.h>
using namespace std;
bool f[55], flag, book[105];
int n;
struct node{
int val, l, r;
}v[55];
int s2i(string s) {
int n;
stringstream ss;
ss << s;
ss >> n;
return n;
}
int bfs(int root) {
queue<pair<int, int> >q;
q.push(make_pair(root, 1));
int last;
while(q.size()) {
if(flag) break;
pair<int, int> now = q.front();
last = now.first;
q.pop();
int ind1 = now.second * 2, ind2 = ind1 + 1;
if(v[last].l != -1) {
if(ind1 > n) flag = 1;
else q.push(make_pair(v[last].l, ind1));
}
if(v[last].r != -1) {
if(ind2 > n) flag = 1;
else q.push(make_pair(v[last].r, ind2));
}
}
return last;
}
int main() {
string l, r;
scanf("%d",&n);
for(int i = 0; i < n; i++) {
cin >> l >> r;
if(l == "-") {
if(r == "-") v[i].l = v[i].r = -1;
else flag = 1;
}
else {
v[i].l = s2i(l), f[v[i].l] = 1;
if(r == "-") v[i].r = -1;
else v[i].r = s2i(r), f[v[i].r] = 1;
}
}
int root;
for(int i = 0; i < n; i++) {
if(!f[i]) {
root = i;
break;
}
}
int last = bfs(root);
if(flag) printf("NO %d",root);
else {
printf("YES %d",last);
}
return 0;
}
ac代码
#include<bits/stdc++.h>
using namespace std;
bool f[55], flag = 0;
int n, maxInd;
struct node{
int val, l, r;
}v[55];
int s2i(string s) {
int n;
stringstream ss;
ss << s;
ss >> n;
return n;
}
int bfs(int root) {
queue<pair<int, int> >q;
q.push(make_pair(root, 1));
int last;
while(q.size()) {
pair<int, int> now = q.front();
q.pop();
last = now.first;
maxInd = max(maxInd, now.second);
int ind1 = now.second * 2, ind2 = ind1 + 1;
if(v[last].l != -1) {
q.push(make_pair(v[last].l, ind1));
}
if(v[last].r != -1) {
q.push(make_pair(v[last].r, ind2));
}
}
return last;
}
int main() {
string l, r;
cin >> n;
for(int i = 0; i < n; i++) {
cin >> l >> r;
if(l == "-") v[i].l = -1;
else v[i].l = s2i(l), f[v[i].l] = 1;
if(r == "-") v[i].r = -1;
else v[i].r = s2i(r), f[v[i].r] = 1;
}
int root;
for(int i = 0; i < n; i++) {
if(!f[i]) {
root = i;
break;
}
}
int last = bfs(root);
if(maxInd != n) printf("NO %d",root);
else {
printf("YES %d",last);
}
return 0;
}