个人感觉
星期六早上的校赛,八道题目都是以前出过的,三道考了全排列!!
直接看题目的话
第一题福尔摩斯密码没读懂,考完试想了想是哈希表
第二题蚂蚁一看就很复杂就先不做了(一般这种题目想出来要花很多时间,不值得,决定回头再做)
然后其它题目稍微有一点复杂,但是冷静下来理清思路就行了,12:30考试结束,我只写了5题(其中间隔字母和最大数我没有考虑周全),其中转向那道题脑子有一点混乱,今晚测试的时候发现有一些案例不能通过,改好之后就行了
然后我觉得最后一题,给数字和加减符号还有括号求最大数,我觉得那个括号根本没有必要,因为乘法有交换律,每次都选最大的两个数相加,再相减就行了。
最后一题是我没有考虑周全 orz,有括号的时候要额外判断
下面写代码
题目和代码
密码匹配
后面想了想写了出来
#include<bits/stdc++.h>
using namespace std;
long long int sum=0;
int main()
{
//最长串
string str;
cin>>str;
int n;
cin>>n;
int ans=0;
for(int i=0;i<n;i++)
{
string temp;
cin>>temp;
//注意初始化
int mpm[26]={0};
for(int i=0;i<temp.size();i++)
{
mpm[temp[i]-'a']++;
}
int index=0;
while(index+8!=str.size()+1)
{
bool ok=true;
int mps[26]={0};
for(int i=index;i!=index+8;i++)
{
mps[str[i]-'a']++;
}
for(int i=0;i<26;i++)
{
if(mps[i]!=mpm[i])
{
// cout<<mps[i]<<" "<<mpm[i]<<endl;
ok=false;
break;
}
}
if(ok)ans++;
index++;
}
}
cout<<ans;
}
蚂蚁
思维题,没想明白
https://blog.csdn.net/wr132/article/details/50791505
#include<bits/stdc++.h>
using namespace std;
int main()
{
int num[60];
int n;
cin>>n;
vector<int>lfnum;
vector<int>rfnum;
int L=0,R=0;
int start=0;
int f=0;
for(int i=0;i<n;i++)
{
cin>>num[i];
if(i==0)
{
start=num[i];
if(start>0) f=1;
else f=-1;
continue;
}
if(num[i]>0&& abs(num[i]) <abs(start) )
{
L++;
}
if(num[i]<0&&abs(num[i])>abs(start))
{
R++;
}
}
if((f==1&&R==0)||(f==-1&&L==0))
{
cout<<1;
}
else cout<<R+L+1;
// cout<<R+L+1;
}
稍大的串
串可以按照字典序进行比较。例如:
abcd 小于 abdc
如果给定一个串,打乱组成它的字母,重新排列,可以得到许多不同的串,在这些不同的串中,有一个串刚好给定的串稍微大一些。科学地说:它是大于已知串的所有串中最小的串。你的任务就是求出这个“稍大的串”。
样例输入:
输入串:
abfxy
样例输出:
abfyx
样例输入:
输入串:
ayyyxxff
样例输出:
fafxxyyy
数据规模约定:
输入的串不超过1000个字符。
特例:
如果已知的串已经是所有重组串中最大的,则原样输出读入的那个串。
这道题很明显就是考全排列啊 不会写直接GG了,我当时就是忘了怎么写,还好查了标准库想起来上星期发现的next_permutation(),下次全排列的递归想不出来背也要背出来
#include<bits/stdc++.h>
using namespace std;
//vts sort后的所有序列
vector<string> pvt;
void fun(string str)
{
do
{
pvt.push_back(str);
}while(next_permutation(str.begin(),str.end()));
}
bool cmp(string a,string b)
{
return a<b;
}
int main()
{
string str;
cin>>str;
//思路 对str进行sort,然后输出这个str的全排列,然后再按字典序排序,然后定位到原字符串
//然后找它下一个字符串即可
string temp_str=str;
//排序读入的字符串
sort(temp_str.begin(),temp_str.end());
//讲这个字符串的全排列添加到pvt中
fun(temp_str);
//排序pvt
sort(pvt.begin(),pvt.end(),cmp);
// for(int i=0;i<pvt.size();i++)
// {
// cout<<pvt[i]<<endl;
// }
// cout<<pvt.size()<<endl;
int index=0;
for(;index<pvt.size();index++)
{
if(pvt[index]==str) break;
}
if(index==pvt.size()-1) cout<<str;
else cout<<pvt[index+1];
}
转向
哎 写这道题的时候早上脑袋有点懵,没有演算,发现一些测试用例没通过,没办法
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
int ans;
//正着走
int ansA;
//反着走
int ansB;
//无论大小 a和b永远有正着走和反着走 且它们的大小一定一样 只不过正负号不一样
//只处理a<b的情况 如果输入a>b 交换 并且修改接下来的正负号
bool flag=true;
if(a>b)
{
swap(a,b);
flag=false;
}
if(a==b)
{
cout<<0;
}
else
{
ansA=-((a+360-b)%360);
ansB=b-a;
//如果之前发生了交换
if(flag==false)
{
ansA=-ansA;
ansB=-ansB;
}
//判断规则
if(abs(ansA)>abs(ansB))
{
cout<<ansB;
}
else if(abs(ansA)<abs(ansB))
{
cout<<ansA;
}
else
{
cout<<ansA>0?ansA:ansB;
}
}
//一些特殊的案例无法通过! 如181 180!
// if(a>b)swap(a,b);
// //从a到b可以走正的也可以走负的
// //1.b-a 2.a-b
// //1.180-70 -70-180
// //45 270= 225 -135
// int ansA=b-a;
// //ansB= (a+x)%360=b
// int ansB=-(360+(a-b));
// cout<<ansA<<" "<<ansB<<endl;
// if(abs(ansA)>abs(ansB)) cout<<ansB;
// else if(abs(ansA)<abs(ansB)) cout<<ansA;
// else printf("%d",ansA>0?ansA:ansB);
}
1-偏差数列
全排列 会就是会 不会也没办法
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > vtt;
int main()
{
//对从1到n生成全排列
//然后找符合 ni-i<=1 的序列
int n;
cin>>n;
vector<int> vt;
for(int i=1;i<=n;i++) vt.push_back(i);
do
{
vtt.push_back(vt);
}
while(next_permutation(vt.begin(),vt.end()));
int ans=0;
for(int i=0;i<vtt.size();i++)
{
bool ok=true;
for(int j=0;j<vtt[i].size();j++)
{
if(abs(vtt[i][j]-(j+1))>1)
{
ok=false;
break;
}
}
if(ok) ans++;
}
cout<<ans;
}
递增数列
这道题我一开始想错了,但是后面思路很清晰又推出规律了,因为每次都选一个数放到最左边,那么我对数列中的每个数,将它们放到对应的位置即可。
每个数移动的次数就是它们对应位置的值。
比如说下面的数列
5 4 3 2 1
1 5 4 3 2 =>1 1移动到最左边 1次
1 2 5 4 3 =>1+2 2 移动到最左边 1再移动到最左边 2次
1 2 3 5 4 =>1+2+3 同理 3次
1 2 3 4 5 =>1+2+3+4
注意每次移动要挪位置,不然对某些情况 会计算挪动的次数
应该是贪心的写法吧,不过我的代码好像会超时,对于10万个数据。。
#include<bits/stdc++.h>
using namespace std;
int main()
{
vector<int> vt;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
int temp;
cin>>temp;
vt.push_back(temp);
}
int ans=0;
for(int i=0;i<n;i++)
{
//如果该元素的不在对应位置
if(vt[i]!=i+1)
{
//找到这个元素的位置
int j=0;
for(;j<vt.size();j++)
{
if(vt[j]==i+1) break;
}
//注意 k从找到的位置 一直到遍历中的i位置 依次覆盖值
//我觉得这很有可能超时 但一时想不出更好的方法!
for(int k=j;k>=i;k--)
{
vt[k]=vt[k-1];
}
vt[i]=i+1;
ans+=i+1;
i=-1;
}
}
cout<<ans;
}
最大数
这道题我觉得是最蠢的,因为括号我觉得是没用的,加法有交换律,没必要加括号
事实证明我才是最蠢的
https://blog.csdn.net/yinxiaobao97/article/details/84672987 来源
#include<bits/stdc++.h>
#define maxn 150
using namespace std;
int n,p,q,k;
int a[maxn];
bool cmp(int x,int y){
return x>y;
}
int main(){
cin>>n>>p>>q>>k;
//从1开始读入
for(int i=1;i<=n;i++) cin>>a[i];
//从大到小排
sort(a+1,a+1+n,cmp);
int ans=0;
// 4,3,2,1 :
//2个减号 1个加号 一个括号 最大为:4-(1-2)+3
//2个减号 1个加号 两个括号时:(4-(1-2))+3
//3个减号 1个括号:4-(1-2-3) 两个括号时:(4-(1-2-3))
//无论如何上面结果都是8
//所以有括号的时候,始终是前n-1大的数减去最小的那个数
if(k==0||q==0){
for(int i=1;i<=n;i++){
//如果加好没用完,直接相加
if(i<=p+1) ans+=a[i];
//加号用完了 相减
else ans-=a[i];
}
}
else{
for(int i=1;i<n;i++) ans+=a[i];
ans-=a[n];
}
cout<<ans<<endl;
return 0;
}
间隔字母
这道题挺有意思的,但是我因为太久没写算法 迭代器都忘记怎么写了 ? 弄了好久才知道是
map<char,int>::iterator
一直写反了,后面存到map的时候又直接存数组的下标,弄了好久。事实证明写题目不能停啊!!!
注:
少处理一种情况。。还是错的,答案参考 https://www.cnblogs.com/Patt/p/5672220.html
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
map<char,int> mp;
bool judge(int num)
{
map<char,int>::iterator it;
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++)
{
if(it->second>(num-1)/2+1) return false;
}
return true;
}
int main()
{
//想法错了 这道题要用贪心,我没有考虑到
//abcabc => abacbc
//这种情况 会漏掉一些答案。
//同时 选择字符放置的时候也要判断接下来够不够放,不够的话就要换大一点的字符放
string str;
cin>>str;
int count=str.size();
for(int i=0;i<str.size();i++)
{
mp[str[i]]++;
}
map<char,int>::iterator it;
string ans="";
char pre=' ';
for(int i=0;i<str.size();i++)
{
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++)
{
if(it->second&&it->first!=pre)
{
//这里默认选择这个字符
it->second--;
//如果剩下的字符合格,则放入这个字符
if(judge(count-1))
{
ans+=it->first;
pre=it->first;
count--;
break;
}
//如果不合格 则恢复它的次数
else it->second++;
}
}
}
cout<<ans;
}