7-5 6翻了 - SMU 2024 spring 天梯赛2 (pintia.cn)
6翻了 :
不能用scanf()!=EOF,输入停不下来,用string a,getline(cin,a),读入整个字符串
先判段不为6得字符,直接输出,如果有六,判断有几个连续的六,根据题目要求输出;
注意,如果在循环里面加加,输出数字的时候会跳过读入下一个空格
#include<bits/stdc++.h>
using namespace std;
signed main(){
string a;
int j=0;
getline(cin,a);
for(int i=0;i<a.size();){
if(a[i]!='6'){
cout<<a[i];
i++;
}
else if(a[i]=='6'){
j=i;
while(a[j]=='6'){
j++;
}
if(j-i>9){
cout<<"27";
i=j;
continue;
}
else if(j-i>3){
cout<<"9";
i=j;
continue;
}
else for(;i<j;i++)cout<<'6';
}
}
return 0;
}
连续因子:
7-8 连续因子 - SMU 2024 spring 天梯赛3(补题) (pintia.cn)
知识点:连续12个数字相乘,最小为都有4e9,而2的31次方约等于2e9;
所以可以暴力循环,
如果给的数是素数,就直接输出最长长度是1,最小连续序列是他本身,
如果不是素数,从2开始循环,在用一个for循环,定义一个s,表示连续数字相乘的结果,结束条件为累乘结果大于n;长度相同时,只存在一个最小连续因子序列。
注意:长度len要初始化,start 也是
#include<bits/stdc++.h>
using namespace std;
#define int long long int
bool prime(int x){
for(int i=2;i<=sqrt(x);i++){
if(x%i==0){
return 0;
}
return 1;
}
}
signed main()
{
int n,len=0,start=0;
cin>>n;
int s=0;
if(prime(n))cout<<1<<endl<<n<<endl;
else {
for(int i=2;i<=sqrt(n);i++){
s=1;
for(int j=i;j*s<=n;j++){
s*=j;
if(n%s==0&&j-i+1>len){
start=i;
len=j-i+1;
}
}
}
cout<<len<<endl;
for(int i=start;i<start+len;i++){
if(i==start)cout<<i;
else cout<<"*"<<i;
}
}
return 0;
}
哈利·波特的考试:
7-9 哈利·波特的考试 - SMU 2024 spring 天梯赛3(补题) (pintia.cn)
求最短路算法floyd:最初始的表(点到点的距离)0行0列不会有变化,对角线数字不会有变化,
题目要求找到一种动物可以变为任何一种动物,且要求魔咒最短,(例:不是鼠——>猫——>鱼,而是鼠——>猫,鼠——>鱼,),所以求出每一种动物变成其他动物的最短字符数,在最短路表中找出每一种动物变为最长字符的数字,每种动物的最长字符取最小的即是答案
#include<bits/stdc++.h>
using namespace std;
int n,m;
int g[105][105];
void floyd(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
if(g[k][j]>g[j][i]+g[i][k]&&k!=i&&k!=j&&i!=j){
g[k][j]=g[j][i]+g[i][k];
}
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
g[i][j]=0x3f3f3f;
}
}
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
g[a][b]=c;
g[b][a]=c;
}
floyd();
int dist[105];
memset(dist,0,sizeof(dist));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dist[i]<g[i][j]&&i!=j){
dist[i]=g[i][j];
}
}
}
int form=0;
int maxx=0x3f3f3f;
for(int i=1;i<=n;i++){
if(maxx>dist[i]){
maxx=dist[i];
form=i;
}
}
if(maxx==0x3f3f3f)cout<<"0";
else cout<<form<<" "<<dist[form];
}
文件传输:
7-12 文件传输 - SMU 2024 spring 天梯赛3(补题) (pintia.cn)
并查集:
找父亲结点用findd(x)!!!!不是fa[x];
#include<bits/stdc++.h>
using namespace std;
int fa[10004];
int findd(int x){
if(fa[x]==x)return x;
return fa[x]=findd(fa[x]);
}
int main(){
int n;
cin>>n;
for(int i=0;i<=n;i++){
fa[i]=i;
}
for(int i=0;;i++){
char a;
int b,c;
cin>>a;
if(a=='S')break;
cin>>b>>c;
if(a=='I'){
fa[findd(c)]=findd(b);
}
else{
if(findd(c)==findd(b))cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
}
int sum=0;
for(int i=1;i<=n;i++){
if(fa[i]==i){
sum++;
}
}
if(sum==1)cout<<"The network is connected.";
else cout<<"There are "<<sum<<" components."<<endl;
return 0;
}
病毒溯源:
、7-11 病毒溯源 - SMU 2024 spring 天梯赛3(补题) (pintia.cn)
图论题+dfs:
因为题目要求如果长度一样就要输出序列最小,所以建图的时候用set默认从小到大进行存图;
用dfs来检测最深深度,
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+20;
int n,k;
set<int>v[N];
int st[N];//标记是否为儿子结点
int dep[N];//记录最长深度
int fa[N];//记录父亲结点;
int ans[N];//记录最长长度的最小卢携
int root,maxn;//最长深度
int maxi;//记录最低端的儿子
void dfs(int u){
for(auto son:v[u]){//son是u的儿子
dep[son]=dep[u]+1;
if(dep[son]>maxn)maxn=dep[son],maxi=son;
dfs(son);
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
for(int i=0;i<n;i++){
cin>>k;
for(int j=1;j<=k;j++){
int u;
cin>>u;
v[i].insert(u);
fa[u]=i;//记录每个结点的父节点
st[u]=1;//记录哪些点儿子,要找出唯一的根节点
}
}
for(int i=0;i<n;i++){
if(!st[i])root=i;
//找出父节点
}
maxn=1;//初始化最长长度
maxi=root;//初始化根节点
dep[root]=1;//初始化长度。记录每个点的深度
dfs(root);
int pos=maxi;//从最底端的结点网上找;
cout<<maxn<<endl;
for(int i=maxn;i>=1;i--){
ans[i]=pos;
pos=fa[pos];
}
for(int i=1;i<=maxn;i++){
cout<<ans[i];
if(i!=maxn-1)cout<<" ";
}
return 0;
}
估值一亿的AI代码:
7-7 估值一亿的AI核心代码 - SMU 2024 spring 天梯赛2(补题) (pintia.cn)
用reverse将字符反转去掉开头和结尾的空格,用isalpha()和isdigit()函数判断空格两边是否为数字或者字符,在主函数里可以写一个auto f=[&](const string& k,const string &v )调用他;。。。,如果需要更改内容,需要判断两边是否为字母或者数字,或者是否在边界;
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main () {
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
string s;
getline(cin, s);
while (n--) {
getline(cin, s);
cout << s << "\nAI: ";
while (s.back() == ' ') s.pop_back();
reverse(s.begin(), s.end());
while (s.back() == ' ') s.pop_back();
reverse(s.begin(), s.end());
string ans;
int cnt = 0;
for (auto& c : s) {
if (c == ' ') {
cnt++;
} else if (isalpha(c) || isdigit(c)) {
if (cnt) ans += ' ';
if (isupper(c) && c != 'I') c -= 'A' - 'a';
ans += c;
cnt = 0;
} else {
if (c == '?') c = '!';
ans += c;
cnt = 0;
}
}
auto f = [&] (const string& k, const string&v) {
int now = -1;
while ((now = ans.find(k, now + 1)) != ans.npos) {
int ok = 0;
if (now - 1 < 0 || !isalpha(ans[now-1]) && !isdigit(ans[now-1])) {
ok++;
}
if (now + k.size() >= ans.size() || !isalpha(ans[now + k.size()]) && !isdigit(ans[now + k.size()])) {
ok++;
}
if (ok == 2) {
ans.erase(now, k.size());
ans.insert(now, v);
}
}
};
f("can you", "IS can");
f("could you", "IS could");
f("I", "you");
f("me", "you");
for (int i = 0; i < ans.size(); i++) {
cout << ans[i];
if (ans[i] == 'I' && i + 1 < ans.size() && ans[i+1] == 'S') {
i++;
}
}
cout << '\n';
}
红色警报:
7-10 红色警报 - SMU 2024 spring 天梯赛2(补题) (pintia.cn)
用并查集解决此类(连通)问题;
每一次就开始攻占之前,做一次并查集,求出有几个不连通的量,攻占城市之后,标记该城市,然后对未标记的城市做一遍并查集,判断此时的根节点和之前的比较有没有减少;设攻占之前的节点数为before,攻占之后的节点数为after,如果before==after则说明攻占没有破坏他的连通性,如果after<before说明被破坏的城市为孤立城市,也不会报警,但若是before<after 结点的增加说明连通性被破坏了,则需要抱紧;他删了那个点是不会复原的。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 505;
int fa[MAXN],n,m,k,ans;
bool vis[MAXN];
struct node
{
int x,y;
}no[5005];
int find(int x)
{
if(fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}
void Union(int x,int y)
{
int xx = find(x);
int yy = find(y);
if(xx != yy)
fa[xx] = yy;
}
int main()
{
int city;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)fa[i] = i;
for(int i=1;i<=m;++i)
{
scanf("%d%d",&no[i].x,&no[i].y);
Union(no[i].x,no[i].y);
}
for(int i=0;i<n;++i)if(fa[i]==i) ans++;//记录有几个不连通的点
scanf("%d",&k);
while(k--)
{
int cnt = 0;
scanf("%d",&city);
vis[city] = 1;
for(int i=0;i<n;++i) fa[i] = i;
for(int i=1;i<=m;++i){
if(!vis[no[i].x] &&!vis[no[i].y])
Union(no[i].x,no[i].y);
}
for(int i=0;i<n;++i) if(!vis[i]&&fa[i]==i) cnt++;
if(cnt <= ans)
printf("City %d is lost.\n",city);
else
printf("Red Alert: City %d is lost!\n",city);
ans = cnt;
if(ans == 0)
{
printf("Game Over.\n");
return 0;
}
}
return 0;
}
排座位:
7-11 排座位 - SMU 2024 spring 天梯赛2(补题) (pintia.cn)
并查集:
朋友的朋友也是我的朋友!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include <bits/stdc++.h>
using namespace std;
int fa[105];
int enemy[105][105];
int find(int x){
if(fa[x]==x)return x;
else return fa[x]=find(fa[x]);
}
int main(){
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
if(c==-1){
enemy[a][b]=1;
enemy[b][a]=1;
}
else{
if(find(a)!=find(b)){
fa[find(b)]=find(a);
}
}
}
for(int i=1;i<=k;i++){
int x,y;
cin>>x>>y;
if(find(x)==find(y)&&enemy[x][y]==0){
cout<<"No problem"<<endl;
}
else if(find(x)==find(y)&&enemy[x][y]==1){
cout<<"OK but..."<<endl;
}
else if(find(x)!=find(y)&&enemy[x][y]==0){
cout<<"OK"<<endl;
}
else if(find(x)!=find(y)&&enemy[x][y]==1)
cout<<"No way"<<endl;
}
return 0;
}