【无标题】

 

#include <bits/stdc++.h>
using namespace std;
int flag=1;
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int minn = 1e9;
        int N;
        cin >> N;
        string s;
        cin >> s;
        int temp;
        for (char i = 'a'; i <= 'z'; ++i)//从一头一尾开始遍历26个字母
/*
如果头尾指针相同,则向中间移动,如果不同,且有一个是当前选定字母,则该指针向中间移动,若没有当前选定字母,则continue继续选定下一字母

*/
        {
            temp = 1e9;
            int l = 0, r = N - 1;
            int num = 0;
            while (l < r)
            {
                if (s[l] == s[r])
                {
                    ++l;
                    --r;
                }
                else
                {
                    if (s[l] == i)
                    {
                        ++l;
                        num++;
                        if(r<l||s[l]!=i&&s[l]!=s[r]){
                            flag=0;
                            break;
                        }
                    }
                    else if (s[r] == i)
                    {
                        --r;
                        num++;
                        if(r<l||s[r]!=i&&s[l]!=s[r]){
                            flag=0;
                            break;
                        }
                    }
                    else
                    {
                        flag=0;
                        break;
                    }
                }
            }
            if(flag)
                minn = min(num, minn);
            flag=1;
        }
        if (minn == 1e9)
            printf("%d\n", -1);
        else
            printf("%d\n", minn);
    }
}

 先将所有子区间i到j的乘积计算并存储,然后区间dp求出所有区间乘积差平方取最大值

#include<bits/stdc++.h>
using namespace std;
//dp[l][r]=max(dp[l][k]+dp[k+1][r]+(xl,k-xk+1,r)^2,dp[l][r])
const int mod=1000003;
long long dp[305][305];
long long s[305][305],v[305];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;++i)
    {
        cin>>v[i];
    }
    for(int i=1;i<=n;++i)
    {
        s[i][i]=1;
        s[i][i-1]=1;
        for(int j=i;j<=n;++j)
        {
            s[i][j]=(v[j]*s[i][j-1])%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]+(s[i][k]-s[k+1][j])*(s[i][k]-s[k+1][j]));
            }
        }
    }
    cout<<dp[1][n]<<endl;

 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+2;
int flag=0;
int a[N];
int dfs(int n,int gcd) {
	if(n==gcd){
		flag=1;
		return 1;
	}
	if(n%2==0){
		dfs(n/2,gcd);
	}
	if(n%3==0){
		dfs(n/3,gcd);
	}
}
int main() {
	int T;
	cin>>T;
	while(T--) {
		int n;

		cin>>n;
		int minn=1e9+1;
		int gcd1=1e9+1;
		int gcd2=1e9+1;
		for(int i=0; i<n; ++i) {
			scanf("%d",&a[i]);
			if(i>0) {

				gcd1=min(gcd1,__gcd(a[i],a[i-1]));
				gcd2=min(gcd1,gcd2);//用o(n)求出所有数最小公约数
			}
		}
		for(int i=0; i<n; ++i) {
			flag=0;
				dfs(a[i],gcd2);//若a[i]能经过若干次除以2或除以3得到最小公约数,则符合要求
				if(!flag)
{
					break;
				}
			
		}

	
	if(flag) {
		cout<<"YES"<<endl;
	} else {
		cout<<"NO"<<endl;
	}
	flag=0;
}
}

 我们只需要求出总字符串子字符串数量,选定任意字母,求出不包含该字母的所有子区间数量,剩下的就是包含该字母的区间数

#include <bits/stdc++.h>
using namespace std;
const long long N = 1e7 + 2;
long long cal(long long x)
{
    return x * (x + 1) / 2;
}
int main()
{
    string s;
    cin >> s;
    long long ans = 0;
    long long sum = cal(s.length());
    for (char i = 'a'; i <= 'z'; ++i)
    {
        if (s.find(i) == -1)
        {
            continue;
        }
        long long cnt = 0;
        long long last = -1;
        for (long long j = 0; j < s.length(); ++j)
        {
            if (i == s[j])
            {
                cnt += cal(j - last - 1);

                last = j;

            }
            else if (j == s.length() - 1)
            {
                cnt += cal(j - last);
            }

        }
        ans += sum - cnt;
    }
    cout << ans;
}

 这道题的关键是选择如何快速的选择两个不同的关键字最小值,因此我们可以创建两个set容器,键为pair容器,价格和口感在两个容器分别作为第一关键字,另一个作为第二关键字,set有自动排序功能,因此在判断是否重复时可以使用lower_bound函数,在删除时,选择对应作为第一关键字容器删除头部即可,另一容器删除元素交换关键字位置就行

#include<bits/stdc++.h>
using namespace std;
struct juruo
{
    int w,t;
    /* data */
};

set<pair<int,int>>s1,s2;

int main()
{
    int n;
    cin>>n;
    while(n--){
        int o;
        cin>>o;
        int w,t;
        if(o==1){
            cin>>w>>t;
            auto it1=s1.lower_bound({w,-1});
            auto it2=s2.lower_bound({t,-1});
            if(it1->first==w||it2->first==t){
                continue;
            }
            else{
                s1.insert({w,t});
                s2.insert({t,w});
            }
        }
        else if(o==2){
            auto it1=s1.lower_bound({-1,-1});
            s1.erase({it1->first,it1->second});
            s2.erase({it1->second,it1->first});
        }
        else if(o==3){
            auto it1=s2.lower_bound({-1,-1});
            s2.erase({it1->first,it1->second});
            s1.erase({it1->second,it1->first});

        }
    }
    long long sum=0;
    for(auto it=s1.begin();it!=s1.end();++it)
    {
        sum+=it->first;
    }
    cout<<sum;
}

 这题只要将所有数从小到大排序,如果对任意数而言,当前数与前一个数之差小于等于k,就可以连上,就有获胜的可能

#include <bits/stdc++.h>
using namespace std;
int n, K;
int cur;
const int N = 1e5 + 2;
int a[N];
int main()
{
    cin >> n >> K;
    for (int i = 0; i < n; ++i)
    {
        cin >> a[i];
    }
    sort(a, a + n);
    cur = 1;
    for (int i = 1; i < n; ++i)
    {
        if (a[i]-a[i-1]<=K)
        {
            cur++;
        }
        else
        {
            cur = 1;
        }
    }
    cout << cur << endl;
}

 这题使用全排列函数next_permutation就能轻松过

#include <bits/stdc++.h>
using namespace std;
int p[101];
int n;
int x;
int num;
    int cur = 1;
void myprint()
{
    for (int i = 1; i <= num; ++i)
    {
        if (i == 1)
            printf("%d", p[1]);
        else
            printf(" %d", p[i]);
    }
    printf("\n");
}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> x;
        for (int j = cur; j < cur + x; ++j)
        {
            p[j] = i;
        }
        cur += x;
        num += x;
    }
    //cout << cur << endl;
    do
    {
        myprint();
        /* code */
    } while (next_permutation(p + 1, p + cur));
}

 

#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        string s;
        cin >> s;
        bool flag = 1;
        string str = s + s;//s+s可以理解为包含循环子串总子串
        for (int len = 2; len <= n; ++len)
        {
            for (int i = 0; i + len <= n; ++i)
            {
                string res = s.substr(i, len);//每次从当前位置截取一部分子串
                reverse(res.begin(), res.end());//翻转子串
                if (str.find(res) == str.npos)//如果在总子串无法找到翻转子串,说明不存在改子串的循环子串
                {
                    cout << "NO" << endl;
                    flag = 0;
                    break;
                }
            }
            if (!flag)
                break;
        }
        if (flag)
            cout << "YES" << endl;
    }
}

 

 只需要用map容器存储每一个数加上c的值,在遍历所有数,若容器存在该关键词,则ans+=mp[该数];

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
const int N = 1e5 + 2;
int a[N];
long long ans;
map<int, int>mp;
int main() {
	int n, c;
	cin >> n >> c;
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
		int x = a[i] + c;
		mp[x]++;
		
	}
	
	for (int i = 0; i < n; ++i) {
		
		if (mp[a[i]]) {
			ans += mp[a[i]];
		}
	}
	cout << ans;
}

 

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 2;
int a[N], f[N];
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n, num;
    cin >> num >> n;
    vector<int> v(n);
    for (int i = 0; i < n; ++i)
    {
        cin >> v[i];
        a[v[i]] = -1;
    }
    queue<int> que;
    que.push(num);
    int res = 0;
    while (!que.empty() && n)
    {
        int len = que.size();
        for (int i = 0; i < len; ++i)
        {
            int ans = que.front();
            que.pop();
            if (a[ans] == -1)
            {
                a[ans] = res;
                --n;
            }
            if (ans * 3 < N && f[ans * 3] == 0)
            {
                que.push(ans * 3);
                f[ans * 3] = 1;
            }
            if (ans * 2 < N && f[ans * 2] == 0)
            {
                que.push(ans * 2);
                f[ans * 2] = 1;
            }
            if (ans + 1 < N && f[ans + 1] == 0)
            {
                que.push(ans + 1);
                f[ans + 1] = 1;
            }
            if (ans - 1 < N && f[ans - 1] == 0)
            {
                que.push(ans - 1);
                f[ans - 1] = 1;
            }
        }
        res++;
    }
    for (auto i : v)
    {
        cout << a[i] << ' ';
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值