第一题:
第一行T表示有T组来判断,第二行是这个第一组的元素个数,接着是元素的全部输出,,,,不断输出T组
输出是对每一组的判断,如果能排列组成1-2 -3这样的话输出yes不然输出NO
#include<bits/stdc++.h>
using namespace std;
int main(){
int T; cin>>T;
vector<vector<int>>res;
for(int i=0;i<T;i++){
int size;
cin>>size;
vector<int>temp(size);
for(int j=0;j<size;j++)
cin>>temp[j];
res.push_back(temp);
}
/完成输入 开始进行判断
for(int i=0;i<res.size();i++){
int flag=1;
int len=res[i].size();
sort(res[i].begin(),res[i].end());
for(int j=0;j<=len-2;j++){
if(j==0 && res[i][j]!=1){
flag=0;
break;
}
if(res[i][j]+1!=res[i][j+1]){
flag=0;
break;
}
}
if(flag==0)
cout<<"NO"<<endl;
if(flag==1)
cout<<"Yes"<<endl;
}
return 0;
}
第二题:
题目很简单,输入一个字符串,问在字符串尾巴最少添加几个字符能够让新字符串变成回文串!
这个题目fuzhu用的方法非常巧妙,其实还是老实点吧。
假设字符串长度为N,我们直到最长也不会超过N-1个辅助字符,关键在于原始字符串的末尾处有几个字符能够构成回文串了! 我们的答案就是N-末尾回文串最大长度。
为了方便处理,我们将原来的字符串进行倒序,然后固定左端,看看最长的回文串长度!(原来回文,倒序还是回文)
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod =10000;
int main() {
string s;
cin>>s;
int n = s.size();
ull s1 = 0,s2 = 0,ba = 1;
int ans = 1;
int i=0,jj=n-1;
while(i<jj){
string now=s.substr(0,jj+1);
string temp=now;
reverse(now.begin(),now.end());
if(now==temp){ ans=jj+1; break;}
else jj--;
}
cout<<n-ans;
return 0;
}
或者更快的是:
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin>>s;
int n = s.size();
int ans = 1;
for(int j=n-1;j>=1;j--){
int left=0,right=j;
while(left<right){
if(s[left]==s[right]){
left++;right--;
}
else
break;
}
if(left>=right){
ans=j+1;
break;
}
}
cout<<n-ans;
return 0;
}
下面的是高级的写法:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod =10000;
int main() {
string s;
cin>>s;
int n = s.size();
ull s1 = 0,s2 = 0,ba = 1;
int ans = 0;
for(int i=0;i<n;i++){ //从原来序列的尾巴开始找符合回文串的长度,原长度减去这个长度就是我要补上的
s1 = s[i]+s1 *mod; ///加上s[i]是为了和s中的第一个元素相同。每次就会乘mod,但是从第二次开始每个元素
s2 = s2+ s[i]*ba; //每次乘元素分开来而已,也是从第二次开始。因为是回文。所以他们经历的次方肯定是有相同的
ba*=mod;
if(s1 == s2){
ans = i+1;
}
}
cout<<n-ans<<endl;
return 0;
}
第四题 图的题目:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int INF=0x3f3f3f3f;
const int N=55;
vector<pair<int,int> >e[N][2];
int vis[N],dis[2][N];
void dij(int s,int op){
memset(vis,0,sizeof(vis));
memset(dis[op],INF,sizeof(dis[op]));
dis[op][s]=0; //op 就是0 或者1 s是各种节点 x这个节点,1这个op的值是0
priority_queue< pair<int,int> >q;
q.push(make_pair(-dis[op][s],s)); // 和节点相关的东西放进去 x 1 y 0,
while(!q.empty()){
int u=q.top().second; // 取出这个节点
q.pop();
if(vis[u]) continue; //如果这个节点走过了就跳过
vis[u]=1;
int len=e[u][op].size(); //看下这个节点,op是交通方式0打车时间,1是走路时间 x 1 就是从x节点走路连接的各个节点。
for(int i=0;i<len;i++){
int v=e[u][op][i].first; //连接的节点
int w=e[u][op][i].second; //改节点到相应某个到节点的走路时间 或者打车的时间
if(dis[op][v]>dis[op][u]+w){ //
dis[op][v]=dis[op][u]+w;
q.push(make_pair(-dis[op][v],v));
}
}
}
}
/// 主函数
int a[N];
signed main(){
int n,m,x,y;
cin>>n>>m>>x>>y;
for(int i=1;i<=m;i++){
int u,v,p,q;
cin>>u>>v>>p>>q;
e[u][0].push_back(make_pair(v,p)); //0代表是打车时间
e[v][0].push_back(make_pair(u,p));
e[u][1].push_back(make_pair(v,q)); //1代表是走路的时间花费
e[v][1].push_back(make_pair(u,q)); //因为 u点到v点 等于v到u 所以都要给他弄下。 e记录了某点某种方式到达另外点的时间所有记录
}
for(int i=1;i<=n;i++) cin>>a[i]; //a[i]记录了到每个站点打车的等车时间
dij(x,1); //使得dis[1] 走路这个维度记录了 每个节点到x的最短时间
dij(y,0); //使得dis[0] 打车这个维度记录了 每个节点到y的最短时间
int ans=dis[1][y];
for(int i=1;i<=n;i++){
int s1=max(dis[1][i],a[i]); //1是走路
ans=min(ans,s1+dis[0][i]); //0是打车
//是不是dis记录每个点到达终点的最短时间!
}
///dis[1][i]是走路的方式到达i节点花费的最短时间;
//dis[0][i]是打车的方式从y节点到i节点花费的最短时间,所以其实两部分合起来~ 换句话说是从i节点打车到目标节点的最小值
cout<<dis[0][1]<<endl;
return 0;
}
第五题 测试专享题
题目:
输入这个员工的工资类型:N年薪制。M月薪制。 以及薪水 以及犯错类型。 L0不犯错,不扣钱,L1普通犯错,扣钱百分之2%,L2是严重犯错,扣钱百分之4.
如果是月薪制的话扣钱翻倍~~~
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
string work,type;
int salary;
cin>>work;
cin>>salary;
cin>>type;
unordered_map<string,int> map;
map["L0"]=0;
map["L1"]=2;
map["L2"]=4;
map["L1,L2"]=6;
int index=1;
if(work=="M")
index=24; //输出的一年扣除的?
int res;
res=(index*salary*map[type])/100;
cout<<res;
return 0;
}