西南民族大学第十一届程序设计竞赛(同步赛)(回顾补题)
作者:互联网
先贴一波官方题解 这次比赛一道贪心原题,一道矩阵快速幂模板题,总体难度一般,不会的知识点 尺取,树形依赖背包
大模拟没写出来,可惜可惜
直接暴力模拟
#include<bits/stdc++.h>
using namespace std;
vector<int> p;
bool cmp(int a,int b) {
return a>b;
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
p.resize(n);
for(int i=0;i<n;i++) {
scanf("%d",&p[i]);
}
sort(p.begin(),p.end(),cmp);
int sum=p[0]+p[1]+p[2];
if(sum>m)
printf("%d\n",sum);
else
printf("Waiver!");
return 0;
}
首先让我们找出所有不同的字母,它们存在于给定的字符串中。我们首先遍历字符串找到所有不同的字符数量,利用map和尺取维护这个数量,然后更新答案即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
map<char, int> mp;
int main() {
int n;
char s[maxn];
while(~scanf("%d", &n)){
mp.clear();
scanf("%s", s + 1);
for(int i = 1; i <= n; i++)
mp[s[i]]++;
int num = mp.size();
int ans = n;
int l = 1, r = 1;
int now = num;
mp.clear();
while(mp.size() != num) {
mp[s[r]]++;
r++;
}
r--;
while(l <= n - num + 1 && r <= n) {
if(now == num) {
ans = min(ans, r - l + 1);
mp[s[l]]--;
if(mp[s[l]] == 0)
now--;
l++;
}
if(now < num) {
r++;
if(mp[s[r]] == 0)
now++;
mp[s[r]]++;
}
}
printf("%d\n", ans);
}
}
原题,经典贪心,区间贪心需要进行转换。细节见代码
/*
首先求出在x轴上可以设立雷达并投射到某一个岛的区间
之后对于每个区间寻找公共部分,如果存在公共部分,更新
公共部分的尾部,如果不存在,雷达站设立的点数+1
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int MAXN=1011;
struct node{
double l,r;
};
vector<node> p;
bool cmp(node a,node b) {
if(a.l==b.l)
return a.r<b.r;
else
return a.l<b.l;
}
int main(){
int n,cnt=1;
double d;
while(~scanf("%d%lf",&n,&d)) {
if(n==0&&d==0)
break;
p.clear();
bool flag=true;
for(int i=0;i<n;i++) {
double x,y;
scanf("%lf%lf",&x,&y);
if(abs(y)>d)
flag=false;
else {
node temp;
temp.l=x-sqrt(d*d-y*y);
temp.r=x+sqrt(d*d-y*y);
p.push_back(temp);
}
}
printf("Case %d: ",cnt++);
if(!flag) {
puts("-1");
continue;
} else {
sort(p.begin(),p.end(),cmp);
int ans=1;
double start=p[0].r;
for(int i=1;i<n;i++) {
if(start>=p[i].l)
start=min(start,p[i].r);
else {
start=p[i].r;
ans++;
}
}
printf("%d\n",ans);
}
}
return 0;
}
模拟
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1011;
int mat[MAXN][MAXN];
int main() {
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
scanf("%d",&mat[i][j]);
}
}
for(int i=0;i<n;i++) {
for(int j=n-1;j>=0;j--) {
if(j==(n-1))
printf("%d",mat[j][i]);
else
printf(" %d",mat[j][i]);
}
printf("\n");
}
return 0;
}
找规律,比较简单
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
int min1=min(n,m),maxn1=max(n,m);
if(min1==1) {
if(maxn1==1) {
if(k>=1)
puts("Beautiful flowers!");
else
puts("Oh! My poor HJ!");
} else {
if(maxn1==2) {
if(k>=2)
puts("Beautiful flowers!");
else
puts("Oh! My poor HJ!");
} else {
if(k>=2)
puts("Beautiful flowers!");
else
puts("Oh! My poor HJ!");
}
}
} else {
if(min1==2) {
if(k>=2)
puts("Beautiful flowers!");
else
puts("Oh! My poor HJ!");
} else {
if(k>=2)
puts("Beautiful flowers!");
else
puts("Oh! My poor HJ!");
}
}
return 0;
}
F Incompetent Fury of a Single Dog
模拟
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
scanf("%d",&n);
set<char> p;
string s;
cin>>s;
for(int i=0;i<s.length();) {
if(!p.count(s[i])) {
p.insert(s[i]);
i++;
} else
s.erase(i,1);
}
cout<<s.length()<<endl;
cout<<s;
return 0;
}
模拟大法好
#include<bits/stdc++.h>
using namespace std;
map<int,string> p;
vector<int> q;
void init() {
p[1]="do",p[2]="re",p[3]="mi",p[4]="fa",p[5]="sol",p[6]="la",p[7]="si";
}
int main() {
init();
int n;
scanf("%d",&n);
q.resize(n);
for(int i=0;i<n;i++) {
scanf("%d",&q[i]);
}
int cnt=0;
for(int i=0;i<n;i++) {
string s;
cin>>s;
if(s==p[q[i]])
continue;
else
cnt++;
}
printf("%d\n",cnt);
return 0;
}
紫书例题,直接暴力打表
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,t;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
switch(n) {
case 0:{
cout<<"0"<<endl;
break;
}
case 1:{
cout<<"1"<<endl;
break;
}
case 2:{
cout<<"0"<<endl;
break;
}
case 3:{
cout<<"0"<<endl;
break;
}
case 4:{
cout<<"0"<<endl;
break;
}
case 5:{
cout<<"1"<<endl;
break;
}
case 6:{
cout<<"5"<<endl;
break;
}
case 7:{
cout<<"33"<<endl;
break;
}
case 8:{
cout<<"245"<<endl;
break;
}
case 9:{
cout<<"2053"<<endl;
break;
}
case 10:{
cout<<"19137"<<endl;
break;
}
case 11:{
cout<<"196705"<<endl;
break;
}
}
}
return 0;
}
矩阵快速幂裸题
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int M = 1e9+7;
typedef long long ll;
const int mod = 1e9+7;
int n ;
struct mat
{
ll a[15][15];
mat(){ //重载
memset(a,0,sizeof(a));
}
};
mat mul(mat x,mat y)
{
mat res;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
res.a[i][j] = (res.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
return res;
}
ll qpow(int p)
{
mat bas;//基础矩阵
mat res;//单位矩阵
for(int i=0;i<2;i++)
res.a[i][i] = 1;
bas.a[0][0] = bas.a[0][1] = bas.a[1][0] = 1;
bas.a[1][1] = 0;
while(p)
{
if(1&p)
res = mul(res,bas);
bas = mul(bas,bas);
p>>=1;
}
return res.a[0][1];//或者res.a[1][0]
}
int main()
{
while(cin>>n) {
cout<<qpow(n)<<endl; //f[n] = qpow(n)
}
return 0;
}
按照DP写法,每次求和每行前缀和和每列前缀和,然后写挂了,可惜可惜。因为这个矩阵是个方阵,不是像求取最大和那样的写法,正解应当如下:因为答案具有比较明显的单调性,很容易看出这是一道二分的题目,首先预处理二维前缀和,复杂度为O(n^2),然后二分答案,因为预处理了二维前缀和,所以每次check当前答案的复杂度为O(n^2),总体复杂度为O(n^2*logn),即可通过该题。
#include <bits/stdc++.h>
using namespace std;
const int MaxN = 2e3 + 5;
long long a[MaxN][MaxN],k;
int n;
void inti(){
for(int i = 1 ; i <= n ; ++i){
for(int j = 1; j <= n ; ++j){
a[i][j] += a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
}
}
}
bool check(int x){
long long res;
for(int i = x ; i <= n ; ++i){
for(int j = x ; j <= n ; ++j){
res = a[i][j] - a[i - x][j] - a[i][j - x] + a[i - x][j - x];
if(res >= k)
return true;
}
}
return false;
}
int main(){
scanf("%d %lld",&n,&k);
for(int i = 1; i <= n ; ++i)
for(int j = 1;j <= n ; ++j)
scanf("%lld",&a[i][j]);
inti();
int l = 1,r = n,ans = 0;
while(l <= r){
int mid = l + r >> 1;
if(check(mid)){
ans = mid ;
r = mid - 1;
}
else
l = mid + 1;
}
if(!ans)
puts("I'm a Gold Chef!");
else
printf("%d\n",ans);
return 0;
}
Ls_attack 发布了45 篇原创文章 · 获赞 1 · 访问量 6758 私信 关注
标签:第十一届,return,puts,int,else,补题,using,程序设计,include 来源: https://blog.csdn.net/Ls_attack/article/details/104066476