周报

这一周就是打打比赛,除了日常的训练外,还有自己打的一些牛客,cf的题。
周二天梯
7-7 估值一亿的AI核心代码
这道题写的很痛苦,写了两个小时,导致其他的题都没有写,写的时候就是感觉能写出来,随着写的过程中发现细节越难越难处理,代码越来越长。交了之后居然都错了。。。挺无语的。

include

include "algorithm"

include "vector"

include "set"

include "map"

include "cmath"

define int long long

using namespace std;
// // 无论用户说什么,首先把对方说的话在一行中原样打印出来;
// 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
// 把原文中所有大写英文字母变成小写,除了 I;
// 把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词;
// 把原文中所有独立的 I 和 me 换成 you;
// 把原文中所有的问号 ? 换成惊叹号 !;
// 在一行中输出替换后的句子作为 AI 的回答。
void solve(){
string s,ans="";
getline(cin,s);//因为有空格所以用getline
cout<<s<<'\n';
cout<<"AI: ";
int l=0;
int r=s.size()-1;
//去除开头的空格
for(int i=0;i<s.size();i++){
if(s[i]!=' ')
{
l=i;
break;
}
}
去除末尾的空格
for(int i=s.size();i>=0;i--){
if(s[i]!=' '){
r=i;
break;
}
}
对大写字母进行修改,(I)不用修改,把问号改成感叹号
for(int i=l;i<=r;i++) {
if (s[i] >= 'A' && s[i] <= 'Z' && s[i] != 'I')
s[i] += 32;
if(s[i]'?')
s[i]='!';
}
把结果存ans中,这一步是去除空格
for(int i=l;i<=r;i++){
if(s[i]!=' ')
ans+=s[i];
else{
if(s[i+1]>='a'&&s[i+1]<='z'||s[i+1]>='0'&&s[i+1]<='9'||s[i+1]
'I')
ans+=' ';
}
}
//cout<<ans<<'\n';
//把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词;
for(int i=0;i<=ans.size()-1;i++){
if((ans[i]'c'&&(ans[i-1]' '||i0)&&i<ans.size()-6&&ans[i+1]'a'&&ans[i+2]'n'&&ans[i+3]' '&&ans[i+4]'y'&&ans[i+5]'o'&&ans[i+6]'u')&&(i+7>=ans.size()||!isalpha(ans[i+7])))//isalpha() 判断是不是字母
{
cout<<"I can";
i+=6;
}
else if((ans[i]
'c'&&(ans[i-1]' '||i0)&&i<ans.size()-8&&ans[i+1]'o'&&ans[i+2]'u'&&ans[i+3]'l'&&ans[i+4]'d'&&ans[i+5]' '&&ans[i+6]'y'&&ans[i+7]'o'&&ans[i+8]'u')&&(i+9>=ans.size()||!isalpha(ans[i+9])))
{
cout<<"I could";
i+=8;
}
else if(ans[i]'I'&&(ans[i-1]' '||i==0)&&(i+2>=ans.size()||!isalpha(ans[i+1])))
{
cout<<"you";

    }
        //遇到'm',判断到底是不是独立的me
    else if((ans[i]=='m'&&(ans[i-1]==' '||i==0)&&i<ans.size()-1)&&ans[i+1]=='e'&&(i+2>=ans.size()||!isalpha(ans[i+2])))
    {
        cout<<"you";
        i+=1;
    }
    else
        if(ans[i]!=NULL)
            cout<<ans[i];
}
cout<<'\n';

}
signed main() {
int t=1;
cin>>t;
getchar();
while(t--){
solve();
}
return 0;
}
7-10 红色警报

这道题使用暴力+并查集,这道题的思路我倒是想对了,每当敌方侵占一座城堡就从新并查集一遍。遍历一遍求连通集;

include <bits/stdc++.h>

define int long long

using namespace std;
int p[505],n,m;
int ide[505][505];
vector vt;
void init(){
for(int i=0;i<n;i++)
p[i]=i;
for(auto x:vt)//对已经侵占城市赋值成一个比较大的数,让他并查集搜不到
p[x]=503;
}
int bc(int x){
if(p[x]x)
return x;
else
return bc(p[x]);
}
void fg(int x,int y){
int xx=bc(x);
int yy=bc(y);
p[xx]=yy;
}
void solve(){
p[503]=503;
cin>>n>>m;
init();
while(m--){
int a,b;
cin>>a>>b;
fg(a,b);
ide[a][b]=1;
ide[b][a]=1;
}
int num=0;
for(int i=0;i<n;i++)
if(bc(i)
i)
num++;
int k;
cin>>k;
bool f=false;
if(kn)
f=true;
while(k--){
int g;
cin>>g;
vt.emplace_back(g);
for(int i=0;i<n;i++)
ide[i][g]=0,ide[g][i]=0;
int num2=0;
init();//暴力从新赋值
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(ide[i][j]){
fg(i,j);
}
}
}
for(int i=0;i<n;i++)
if(i
bc(i)) {
num2++;//判断有多少个联通块
// cout<<i<<' ';
}
// cout<<num2<<'\n';
if(num2>num)
cout<<"Red Alert: City "<<g<<" is lost!\n";
else
cout<<"City "<<g<<" is lost.\n";
num=num2;
}
if(f)
cout<<"Game Over.";
}
signed main() {
int t=1;
while(t--){
solve();
}
return 0;
}
7-11 排座位
这道题当时没有拿满分,同样是用到了并查集,后面补题的时候发现是最后的判定条件没有写的太严谨

include

include "algorithm"

include "vector"

include "set"

include "map"

include "cmath"

define int long long

using namespace std;
int s[105];
int cha(int x){
if(s[x]x)
return x;
else
return cha(s[x]);
}
int vis[105][105];
void solve(){
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
s[i]=i;
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
if(c
1){
int y=cha(a);
int u=cha(b);
s[y]=u;
vis[a][b]=1;
vis[b][a]=1;
}else
vis[a][b]=c,vis[b][a]=c;
}
while(k--){
int a,b;
cin>>a>>b;
int y=cha(a);
int u=cha(b);
//这个判定条件一定要写的非常的严谨,不然就会挖
if(vis[a][b]1)
cout<<"No problem\n";
else
if(vis[a][b]
-1&&y!=u)
cout<<"No way\n";
else
if(y!=u&&vis[a][b]0)
cout<<"OK\n";
else
if(y
u&&vis[a][b]==-1)
cout<<"OK but...\n";
}
}
signed main() {
int t=1;
while(t--){
solve();
}
return 0;
}
7-15 特殊堆栈

用vector额外存一遍,再用二分和vector本身的插入函数达到一个排序的效果,这样的话求中值的话直接调用vector的下标就可以了,另外的vector的操作跟着stack走就可以了
说实话用vector来起到排序的结果我之前还真的没有想到挺巧妙的

include <bits/stdc++.h>

define int long long

using namespace std;
stack st;
vector vt;
void solve(){
string s;
cin>>s;
if(s"Push"){
int m;
cin>>m;
st.push(m);
vt.insert(lower_bound(vt.begin(),vt.end(),m),m);
}
else
if(s
"Pop"){
if(st.size()0){
cout<<"Invalid\n";
}
else
{
cout<<st.top()<<'\n';
auto it= lower_bound(vt.begin(),vt.end(),st.top());
vt.erase(it);
st.pop();
}
}
else
{
if(st.size()
0)
cout<<"Invalid\n";
else{
if(vt.size()%2==0)
cout<<vt[(vt.size()-1)/2]<<'\n';
else
cout<<vt[(vt.size()-1)/2]<<'\n';
}
}
}
signed main() {
int t;
cin>>t;
while(t--) {
solve();
}
return 0;
}
周六天梯
7-10 列车厢调度
我感觉这道题的难点是在读题上面,题真的很难读懂,应该也算一个模拟吧

include <bits/stdc++.h>

define int long long

using namespace std;
stack st;
string s,k;
vector vt;
void solve() {
cin>>s>>k;
int i,j;
int flag=0;
for(i=0,j=0;i<s.size();i++){
if(s[i]==k[j]){//判断两个字符串每一位的数是否相等,如果相等就直接从1到2,最终的结果用vector来存储
j++;
vt.emplace_back("1->2");
while(1){//这个while循环旨在对stack中值的一个判断,如果可以输进2中就输进去。
if (j<s.size()&&st.size()!=0&&st.top() == k[j]) {
st.pop();
j++;
vt.emplace_back("3->2");
}
else break;
}
}
else{//如果两个值不想等的话,就把车厢放在3轨道里暂时存放
st.push(s[i]);
vt.emplace_back("1->3");
}
}
while(j != k.size()&&st.size()>0){
if(st.top() == k[j]){
st.pop();
vt.emplace_back("3->2");
j++;
}
else{
flag = -1;//判断会不会出错,如果出错了,就修改flag的值
break;
}
}
if(flag == -1)
printf("Are you kidding me?");
else {
for(auto x:vt)
cout<<x<<'\n';
}
}
signed main(){
solve();
}
7-8 连续因子
暴力
首先求出n的每一个因子然后用遍历每一个因子看看有没有连续的

include<bits/stdc++.h>

define int long long

using namespace std;
void solve(){
int n;
cin>>n;
vector vt;
for(int i=2;i<=(long long)sqrt(n);i++){
if(n%i0)
vt.emplace_back(i);
}
int num=0;
int ans=0;
for(int i=0;i<vt.size();i++){
int u=1;
int y=1;
for(int j=i+1;j<vt.size();j++){
if(vt[j]-vt[i]
u){
y++;
u++;
}
else
{
break;
}
}
if(y>num){
ans=vt[i];
num=y;
}
}
if(num0){
cout<<"1\n"<<n;
return;
}
cout<<num<<'\n';
for(int i=0;i<num;i++)
if(i!=num-1)
cout<<ans+i<<'*';
else
cout<<ans+i;
}
signed main(){
solve();
}
7-12 文件传输
这道题其实很简单,就是一个并查集
当时做的时候有一个用例超时了,一直没有检查出来
问题就出在并查集函数那里
int bc(int x){
if(s[x]
x)
return x;
else
return bc(s[x]);
}

int bc(int x){
if(s[x]==x)
return x;
else
return s[x]=bc(s[x]);
}
这两个并查集函数时间复杂度居然不一样,第二个比第一个要快。
修改了一下例子就过了

include<bits/stdc++.h>

//#define int long long
using namespace std;
int s[10005];
int n;
int bc(int x){
if(s[x]x)
return x;
else
return s[x]=bc(s[x]);
}
void megin(int a,int b){
int y=bc(a);
int u=bc(b);
s[y]=u;
}
void solve(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
s[i]=i;
while(1){
char c;
int a,b;
getchar();
c=getchar();
scanf("%d %d",&a,&b);
if(c
'C'){
int y=bc(a);
int u=bc(b);
if(y!=u)
printf("no\n");
else
printf("yes\n");
}
else
if(c'I'){
megin(a,b);
}
else
break;
}
int num=0;
for(int i=1;i<=n;i++){
if(s[i]
i)
num++;
}
if(num==1)
printf("The network is connected.");
else
printf("There are %d components.",num);
}
signed main(){
int t=1;
// cin>>t;
while(t--)
solve();
}
7-11 病毒溯源

一个深搜题,对顶点进行一个排序以达到输出序列最小的结果,用vector存遍历的序列,最后输出即可

include

include "algorithm"

include "vector"

include "set"

include "map"

include "cmath"

define int long long

using namespace std;
int n,ans=0,num=0;
vector<vector> vt(10005);
vector u,gh;
void dfs(int x,int k){
k++;
u.emplace_back(x);
if(vt[x].size()0){
if(k>ans){
ans=k;
gh=u;
}
return;
}
for(int j=0;j<vt[x].size();j++){
dfs(vt[x][j],k);
u.pop_back();
}
}
void solve(){
cin>>n;
for(int i=0;i<n;i++){
int k;
cin>>k;
num+=k;
while(k--){
int a;
cin>>a;
vt[i].emplace_back(a);
}
sort(vt[i].begin(),vt[i].end());
}
for(int i=0;i<n;i++)
dfs(i,0);
if(num
0)
{
cout<<"1\n0";
return;
}
cout<<ans<<'\n';
for(int i=0;i<gh.size();i++){
if(i!=gh.size()-1)
cout<<gh[i]<<' ';
else
cout<<gh[i];
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}

posted @ 2024-03-31 17:27  niubuniu  阅读(5)  评论(0编辑  收藏  举报