A-[NOIP2007]字符串的展开
简单模拟即可
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int p1,p2,p3;
string s;
vector<char> ans;
void rep(char l,char r){//用来生成代替字符串的函数
ans.push_back(l);
if(r<=l){ans.push_back('-');}
else if(r==l+1){}
else {//l-r
if(p1==1 && p3==1){
for(char i=l+1;i<=r-1;i++)
for(int k=0;k<p2;k++)
if(isalpha(l))ans.push_back(tolower(i));
else ans.push_back(i);
}
else if(p1==1){//逆序
for(char i=r-1;i>=l+1;i--)
for(int k=0;k<p2;k++)
if(isalpha(l))ans.push_back(tolower(i));
else ans.push_back(i);
}
else if(p1==2 && p3==1){
for(char i=l+1;i<=r-1;i++)
for(int k=0;k<p2;k++)
if(isalpha(l))ans.push_back(toupper(i));
else ans.push_back(i);
}
else if(p1==2){//逆序
for(char i=r-1;i>=l+1;i--)
for(int k=0;k<p2;k++)
if(isalpha(l))ans.push_back(toupper(i));
else ans.push_back(i);
}
else {
for(int i=0;i<p2*(r-l-1);i++)
ans.push_back('*');
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>p1>>p2>>p3>>s;
int len=s.size();
for(int i=0;i<len-1;i++){
if(s[i+1]=='-'){
if(( isdigit(s[i]) && isdigit(s[i+2]) ) ||
( isalpha(s[i]) && isalpha(s[i+2]) )){
rep(s[i],s[i+2]);
++i;
}
else ans.push_back(s[i]);
}
else ans.push_back(s[i]);
}
ans.push_back(s[len-1]);
for(int i=0;i<ans.size();i++)cout<<ans[i];
return 0;
}
B-[NOIP2017]时间复杂度
2
C-[NOIP2010]机器翻译
注意这里cnt不但可以记录个数,模m后表示字典中下一个要被删除的单词
#include<bits/stdc++.h>
using namespace std;
int dict[110],pas[1010];
int main(){
int m,n,cnt=0;
cin>>m>>n;
for(int i=0;i<n;i++)cin>>pas[i];
for(int i=0;i<n;i++){
bool check=false;
if(cnt<m){
for(int j=0;j<cnt;j++)
if(dict[j]==pas[i]){check=1;break;}
if(!check)dict[cnt++]=pas[i];
}
else {
for(int j=0;j<m;j++)
if(dict[j]==pas[i]){check=1;break;}
if(!check)dict[cnt%m]=pas[i],cnt++;
}
}
cout<<cnt;
}
或者使用find函数(代码量会减少一些)
#include<bits/stdc++.h>
using namespace std;
int dict[110],pas[1010];
int main(){
int m,n,cnt=0;
cin>>m>>n;
for(int i=0;i<n;i++){
cin>>pas[i];
if(cnt<m){
if(find(dict,dict+cnt,pas[i])==dict+cnt)
dict[cnt++]=pas[i];
}
else if(find(dict,dict+m,pas[i])==dict+m)
dict[cnt%m]=pas[i],cnt++;
}
cout<<cnt;
}
提供一种时间复杂度低一些的解法:
注意最后一行是a[cnt-m-1]
#include<bits/stdc++.h>
using namespace std;
//vis用来判断数是否出现过,a用来记录放入的单词
int vis[1010],a[1010],m,n,x,cnt;
int main(){
cin>>m>>n;
for(int i=0;i<n;i++){
cin>>x;
if(vis[x])continue;
a[cnt++]=x;
vis[x]=1;
if(cnt>=m) vis[a[cnt-m-1]]=0;
}
cout<<cnt;
}
D-四舍五入
4
E-安卓图案解锁
1.判断是否重复出现
2.判断是否跳过数字(将横竖斜都判断一遍)
3.将一些边的判断合并,如经过5的,然后(9,1)(3,7)配对判断
ps:详细看代码,结合图理解
#include<bits/stdc++.h>
using namespace std;
int main(){
string s1;
while(cin>>s1){
vector<int> dict,s;
bool check=1;
for(int i=0;i<s1.size();i++)s.push_back(s1[i]-'0');
dict.push_back(s[0]);
for(int i=1;i<s.size();i++){
for(int j=0;j<dict.size();j++){
if(dict[j]==s[i]){check=false;break;}
}
if(s[i]+s[i-1]==10){
if(find(dict.begin(),dict.end(),5)==dict.end()){
check=false;
}
}
if(s[i]==9 || s[i]==1){
if(s[i-1]==3 || s[i-1]==7)
if(find(dict.begin(),dict.end(),(s[i]+s[i-1])/2) == dict.end()){check=false;}
}
if(s[i]==7 || s[i]==3){
if(s[i-1]==1 || s[i-1]==9)
if(find(dict.begin(),dict.end(),(s[i]+s[i-1])/2) == dict.end()){check=false;}
}
dict.push_back(s[i]);
}
if(check)printf("YES\n");
else printf("NO\n");
}
return 0;
}
F- 从后台研发到跑路
2
G-回文数
1.注意前导0(00也算,0不算)(要出现前导0,有且仅有2种数字出现,并且非0的数字只有1个)
2.数量为奇数个的数不超过1个
#include<bits/stdc++.h>
using namespace std;
int a[10];
bool check1=1,check2=0,check=1;
vector<int> ans;
int main(){
for(int i=0;i<10;i++)cin>>a[i];
int cnt=0;//记录奇数个的数的个数
for(int i=0;i<10;i++){if(a[i]&1) cnt++;}
if(cnt>1)check=false;
if(a[0]>=2){
int sum=0;
for(int i=0;i<10;i++){sum+=a[i];}
if(a[0]+1==sum || a[0]==sum){
printf("-1");
return 0;
}
}
if(check){
int ji=-1;
for(int i=0;i<10;i++)if(a[i]&1){ji=i;break;}
for(int i=1;i<10;i++){
if(a[i]>=2){
ans.push_back(i);
a[i]-=2;
break;
}
}
for(int i=0;i<10;i++){
while(a[i]>=2)ans.push_back(i),a[i]-=2;
}
for(int i=0;i<ans.size();i++)cout<<ans[i];
if(ji!=-1)cout<<ji;
for(int i=ans.size()-1;i>=0;i--)cout<<ans[i];
}
else printf("-1");
return 0;
}
H-回文数
1
I-[NOIP2016]玩具谜题
1
J-[NOIP2015]神奇的幻方
按题目所给条件模拟即可
#include<bits/stdc++.h>
using namespace std;
int n;
int a[40][40];
pair<int,int> pos;//记录上一个点的位置
int main(){
cin>>n;
a[1][(1+n)/2]=1;
pos={1,(1+n)/2};
for(int i=2;i<=n*n;i++){
if(pos.first==1 && pos.second!=n){
a[n][pos.second+1]=i;
pos={n,pos.second+1};
}
else if(pos.second==n && pos.first!=1){
a[pos.first-1][1]=i;
pos={pos.first-1,1};
}
else if(pos.first==1 && pos.second==n){
a[pos.first+1][pos.second]=i;
pos={pos.first+1,pos.second};
}
else {
if(a[pos.first-1][pos.second+1]==0){
a[pos.first-1][pos.second+1]=i;
pos={pos.first-1,pos.second+1};
}
else {
a[pos.first+1][pos.second]=i;
pos={pos.first+1,pos.second};
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<a[i][j]<<' ';
}
cout<<endl;
}
return 0;
}
K-Tic-tac-toe
5
L-I love you
dp比较难想到,想到之后挺简单的
#include<bits/stdc++.h>
using namespace std;
char ch;
int dp[8];//表示前i个字符在字符串中出现了dp[i]次
const int p=20010905;
int main(){
string s;
cin>>s;
for(int i=0;i<s.size();i++){
ch=tolower(s[i]);
if(ch=='i')dp[0]++;
if(ch=='l')dp[1]=(dp[1]+dp[0])%p;
if(ch=='o')dp[2]=(dp[2]+dp[1])%p;
if(ch=='v')dp[3]=(dp[3]+dp[2])%p;
if(ch=='e')dp[4]=(dp[4]+dp[3])%p;
if(ch=='y')dp[5]=(dp[5]+dp[4])%p;
if(ch=='o')dp[6]=(dp[6]+dp[5])%p;
if(ch=='u')dp[7]=(dp[7]+dp[6])%p;
}
cout<<dp[7]%p;
}
M-[NOIP2016]回文日期
分解题目:
1.回文函数 2.找到下一个日期 3.闰年判断(当然可以和2合并)
#include<bits/stdc++.h>
using namespace std;
const int run_mon[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
const int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
inline bool run(int year){
if(year%4==0 &&(year%100!=0 || year%400==0)) return true;
return false;
}
inline bool huiwen(int date){
vector<int> s;
while(date>0){
s.push_back(date%10);
date/=10;
}
for(int i=0;i<=(int)s.size()/2;i++){
if(s[i]!=s[s.size()-1-i])return false;
}
return true;
}
inline int next_date(int date){
int year,month,day;
year=date/10000;
month=date/100%100;
day=date%100;
if(run(year)){
day++;
if(day>run_mon[month]){day=1; month++;};
if(month>12){month=1,year++;};
}
else {
day++;
if(day>mon[month]){day=1; month++;};
if(month>12){month=1,year++;};
}
return year*10000+month*100+day;
}
int main(){
int l,r,cnt=0;
cin>>l>>r;
if(huiwen(l))cnt++;
while(next_date(l)<=r){
l=next_date(l);
if(huiwen(l))cnt++;
}
cout<<cnt;
return 0;
}
N-校门外的树
签到
#include<bits/stdc++.h>
using namespace std;
bool tree[10010];
int cnt,l,r,L,M;
int main(){
cin>>L>>M;
for(int i=0;i<M;i++){
cin>>l>>r;
for(int j=l;j<=r;j++)tree[j]=1;
}
for(int i=0;i<=L;i++){
if(tree[i]==0)cnt++;
}
cout<<cnt;
}
O-值周
首先考虑算法可行性:考虑n的规模,时间复杂度要小于nlgn(可以用sort了)
思路:排序后合并区间(见下图)
两个区间有交集的时候,合并成大区间;不然则开辟新区间,并将上一个区间的人赶走
#include<bits/stdc++.h>
#define ll long long
using namespace std;
vector< pair<int,int> > tree;
int cnt,L,M,l,r,len;
bool cmp(pair<int,int> a,pair<int,int> b){
return a.first<=b.first;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>L>>M;
int x,y;
for(int j=0;j<M;j++){
cin>>x>>y;
tree.push_back({x,y});
}
sort(tree.begin(),tree.end(),cmp);
l=tree[0].first,r=tree[0].second;
for(int i=1;i<M;i++){
if(tree[i].first>r+1){
len+=r-l+1;
// cout<<l<<" "<<r<<endl;
l=tree[i].first;
r=max(r,tree[i].second);
}
else {
r=max(r,tree[i].second);
// cout<<l<<" "<<r<<endl;
}
}
len+=r-l+1;
cout<<L+1-len;
}
P-货物种类
1
Q-储物点的距离
2
R-糖糖别胡说,我真的不是签到题
5
S-P1067 [NOIP2009 普及组] 多项式输出
下面提供两种思路:
1.按x的次数进行分类
2.对x的每项进行分类(符号、系数、x、幂数)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a;
int main(){
cin>>n;
for(int i=n;i>=0;i--){
cin>>a;
if(!a)continue;
if(i==n){
if(a==1)cout<<"x^"<<i;
else if(a==-1)cout<<"-x^"<<i;
else cout<<a<<"x^"<<i;
}
else if(i==1){
if(a==1)cout<<"+x";
else if(a==-1)cout<<"-x";
else if(a>0)cout<<"+"<<a<<"x";
else if(a<0)cout<<a<<"x";
}
else if(i==0){
if(a>0)cout<<"+"<<a;
else cout<<a;
}
else{
if(a==1)cout<<"+x^"<<i;
else if(a==-1)cout<<"-x^"<<i;
else if(a>0)cout<<"+"<<a<<"x^"<<i;
else if(a<0)cout<<a<<"x^"<<i;
}
}
return 0;
}
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a;
int main(){
cin>>n;
for(int i=n;i>=0;i--){
cin>>a;
if(!a)continue;
//符号
if(a<0)cout<<'-';
else if(i!=n)cout<<'+';
//系数
if((abs(a)==1 && i==0) || abs(a)!=1)cout<<abs(a);
//x及其幂数
if(i!=0){
if(i==1)cout<<'x';
else cout<<"x^"<<i;
}
}
return 0;
}