2023-ACM-week4

T1.子串分值和

 

思路:

硬做的话会超时,参考大佬的思路用所谓‘贡献度’来思考

我们可以计算每个字符的贡献,并计算他们的贡献和。怎么计算贡献呢?因为区间内重复的字符只算一个,所以对于样例ababc中第一个a字母来说,它能被计数的情况就是从上一个字母a开始(因为没有所以实际上是从它开始),区间长度从1到len的len种情况(虽然到第3个位置也有个字符a,但我们只记录一个,所以记录的还是最先出现的a),那么第一个字母a所能提供的贡献一共就是len,即5。我们再看第二个字母a,和前面说的一样,他能被计数的情况,就是从上一个相同的字母开始,枚举区间长度直到到达字符串末尾,所以第二个字母所能提供的贡献就是:(当前字母位置 - 上一个相同字母)*(区间长度 - 当前字母位置)=2 *3=6;我们只要如法炮制,求得所有字符的贡献,并把计算贡献的总和即可。

代码:

#include<bits/stdc++.h>
using namespace std;
string s;
long long ans,last[26];
int main()
{
    memset(last,-1,sizeof(last));//为了第一个
    cin>>s;
    int n=s.size();
    for(int i=0;i<n;i++)
    {
        ans+=(i-last[s[i]-'a'])*(n-i);
        last[s[i]-'a']=i;
    }
    cout<<ans;
}

T2.循环字串

思路:

只需要把给的字串跟自己相加,再把原来的字串反转,判断是否是相加后新字符串的字串

代码:

#include<bits/stdc++.h>
using namespace std;
int n,t;
string s;
int main()
{
    cin>>t;
    while(t--)
    {
        bool flag=true;
        cin>>n>>s;
        string s1=s,s2=s+s;
        reverse(s1.begin(),s1.end());
        int idx=s2.find(s1);//好用的函数
        if(idx<0)flag=false;
        if(flag)cout<<"YES"<<'\n';
        else cout<<"NO"<<'\n';
    }
}

T3.整齐的数组

思路:

这个题其实就是找出除了最小值之外,其余值到最小值的距离的最大公约数,求全部的公约数:就是将数组全部遍历一遍即可,得到最后的gcd。除此之外当数组中的数全部相同时gcd为0。

代码: 

#include<bits/stdc++.h>
using namespace std;
int n,a[45];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int ans=0,minn=0x3f3f3f3f;
        memset(a,0x3f3f3f3f,sizeof(a));
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            minn=min(a[i],minn);
        }
        for(int i=1;i<=n;i++)
            ans=__gcd(a[i]-minn,ans);
        if(ans==0)cout<<-1<<endl;
        else cout<<ans<<endl;
    }
}

T5.快快变大

思路:

思路类似于蓝桥杯的那题 ‘石子合并’

最主要的dp递推:dp[i][j]=max(dp[i][j],dp[i][k] + dp[k + 1][j] + (cheng[i][k]-cheng[k+1][j])^2),cheng表示i到j乘积,k从i+1递增到i+len-2。

代码:

#include<bits/stdc++.h>
using namespace std;
const int mod=1000003;
long long n,a[305],dp[305][305],mtp[305][305];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        mtp[i][i]=1;
        mtp[i][i-1]=1;
        for(int j=i;j<=n;j++)
            mtp[i][j]=(mtp[i][j-1]*a[j])%mod;//预处理求出前缀积
    }
    for(int len=2;len<=n;len++)//长度
        for(int i=1;i+len-1<=n;i++)//起点
        {
            int j=i+len-1;//终点
            for(int k=i;k<j;k++)//开始枚举
                dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+(mtp[i][k]-mtp[k+1][j])*(mtp[i][k]-mtp[k+1][j]));
        }
    cout<<dp[1][n];
}

T6.蒟蒻

思路:

模拟题,按照题目意思一步一步做下来就好啦

代码: 

#include<bits/stdc++.h>
using namespace std;
int n,op,w,t,ans,idx;
struct GD
{
    int cost;
    int val;
}jelly[100005];

bool cmp1(GD a,GD b)
{
    return a.cost<b.cost;
}
bool cmp2(GD a,GD b)
{
    return a.val<b.val;
}
void cheap()
{
    sort(jelly+1,jelly+1+idx,cmp1);
    idx--;
    for(int i=1;i<=idx;i++)
        jelly[i]=jelly[i+1];
}
void bad()
{
    sort(jelly+1,jelly+1+idx,cmp2);
    idx--;
    for(int i=1;i<=idx;i++)
        jelly[i]=jelly[i+1];
}
int main()
{
    cin>>n;
    while(n--)
    {
       cin>>op;
       if(op==1)
       {
            bool flag=true;
            cin>>w>>t;
            for(int i=0;i<=idx;i++)
                if(jelly[i].cost==w||jelly[i].val==t)
                {
                    flag=false;
                    break;
                }
            if(flag)
            {
                idx++;
                jelly[idx].cost=w;
                jelly[idx].val=t;
            }
       }
       else if(op==2) cheap();
       else bad();
    }
    for(int i=1;i<=idx;i++)
        ans+=jelly[i].cost;
    cout<<ans;
}

 T7.进制转换

思路:

先转换成十进制来做加法,最后在转化成给定进制输出,可以共两个函数来实现这两个功能

代码:

#include<bits/stdc++.h>
using namespace std;
long long ans=0;
string strans;
long long solve1(int t,string s)
{
	long long x=0;
	long long k=1;
	for(int i=s.length()-1;i>=0;i--)
	{
		int a;
		if(s[i]>='0'&&s[i]<='9') a=s[i]-'0';
		if(s[i]>='A'&&s[i]<='Z') a=s[i]-'A'+10;
		if(s[i]>='a'&&s[i]<='z') a=s[i]-'a'+36;
		x=x+a*k;k*=t;
	}
	return x;
}
void slove2(long long ans,int m)
{
	while(ans)
	{
		int k=ans%m;
		ans/=m;
		if(k>=0&&k<=9) strans+='0'+k;
		if(k<=35&&k>=10) strans+='A'+(k-10);
		if(k<=61&&k>=36) strans+='a'+(k-36);
	}
	for(int i=strans.length()-1;i>=0;i--)
		cout<<strans[i];
}
int main()
{
	int n,m;
    cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int t;
        string s;
		cin>>t>>s;
		ans+=solve1(t,s);
	}
	slove2(ans,m);
}

T9.锦标赛

思路:

这题想到了其实挺简单的。实际上如果有一个能力值a与某一个能力值b满足a>b且差的绝对值大于K,则能力值小于等于b的人都绝对不可能获胜。因为能力值小于等于b的人无论怎么比,最后还是会输给能力值为a的人。因此我们只需要先把能力值升序排序(从左到右依次增大),然后不断在两两之间判断是否差值的绝对值大于K,如果大于K的话,这个能力值大的左边的人全部都标记为不可能获胜。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,k,a[100005];
int main()
{
    cin>>n>>k;
    int tmp;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+1+n);
    for(int i=1;i<n;i++)
    {
        if(a[i+1]-a[i]>k)
            tmp=i;
    }
    cout<<n-tmp;
}

 T10.饿饿,饭饭2

思路:

 如果两个数通过乘上多个2和3可以达到相等,那么反过来,这两个数通过除去多个2和3也可以达到相等。而且这个相除后得到的数应该是这两个数之间的最大公约数。

由于不知道除去多个2和除去多个3的先后顺序,需要通过dfs进行回溯搜索

代码: 

#include<bits/stdc++.h>
using namespace std;
int t,n,num[200005];
bool dfs(int num,int gcd)
{
    if(num<gcd)return false;
    bool flag1=false,flag2=false;
    if(num%2==0) flag1=dfs(num/2,gcd);
    if(num%3==0) flag2=dfs(num/3,gcd);
    return flag1||flag2||num==gcd;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin>>t;
    while (t--)
    {
        bool flag=true;
        memset(num,0x3f3f3f3f,sizeof(num));
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>num[i];
        int gcd=num[1];
        for(int i=1;i<=n;i++)
            gcd=__gcd(num[i],gcd);//求出这几个数的最大公约数
        for(int i=1;i<=n;i++)
            if(!dfs(num[i],gcd))//把这个数除去多个2或3判断能不能变成最大公约数
            {
                flag=false;
                break;
            }
        if(flag)cout<<"YES"<<'\n';
        else cout<<"NO"<<'\n';
    }
}

 

### 回答1: CDC-ACM驱动是一种USB设备驱动程序,用于安装和连接支持CDC ACM规范的通信设备。在Windows 7操作系统中,CDC-ACM驱动程序已经预装,但如果您的USB设备无法正常工作,您可以尝试手动更新或重新安装驱动程序。 首先,在Windows 7操作系统中,您可以通过设备管理器找到CDC-ACM驱动程序。打开设备管理器,找到您的USB设备,右键单击并选择“属性”,然后切换到“驱动程序”选项卡。如果您看到“当前驱动程序”一栏中没有CDC-ACM驱动程序,您可以在此处选择“更新驱动程序”选择CDC-ACM驱动程序并安装。 如果您的USB设备无法连接到计算机,您可以尝试重新安装CDC-ACM驱动程序。首先,您可以从设备制造商的网站下载最新版本的CDC-ACM驱动程序,或者从Windows更新程序中查找更新。然后,您可以将USB设备插入电脑,然后双击CDC-ACM驱动程序进行安装。按照安装向导的指示进行操作,完成驱动程序的安装后,您可以重新连接您的USB设备并测试其是否能够正常工作。 总之,CDC-ACM驱动程序是Windows 7预装的USB设备驱动程序之一。如果您的USB设备无法正常工作,您可以通过更新或重新安装驱动程序来解决问题。如果您有任何疑问或困难,建议您查看设备制造商的帮助文档或寻求专业的技术支持。 ### 回答2: CDC-ACM驱动是一种用于连接设备的万能串行总线设备驱动程序,可用于Windows 7操作系统。常见的CDC-ACM设备包括USB调制解调器、串行数字摄像头、商用POS终端等。 安装CDC-ACM驱动前,需要确认系统已经启用了自动驱动程序安装功能。打开设备管理器,在“通用串行总线控制器”下看到“CDC-ACM设备”或其他相关设备,说明驱动已经被正确识别。如果未自动识别,可以手动安装驱动。 手动安装驱动的步骤是,首先下载安装程序,解压缩后通过设备管理器找到对应设备,右键选择“更新驱动程序软件”,选择“浏览计算机以查找驱动程序软件”,选择解压文件夹中的.inf文件并进行安装。安装完成后,重新插拔设备即可。 总之,CDC-ACM驱动是连接设备的重要工具,对于无法识别的设备或需要手动更新驱动程序的情况,可以采取手动安装驱动的方式进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值