Problem - A - Codeforces

You are given nn integers a1,a2,…,an. Find the maximum value of max(al,al+1,…,ar)⋅min(al,al+1,…,ar)over all pairs (l,r)of integers for which 1≤l<r≤n.

Input

The first line contains a single integer tt (1≤t≤10000)  — the number of test cases.

The first line of each test case contains a single integer nn (2≤n≤105).

The second line of each test case contains nn integers a1,a2,…,an (1≤ai≤106).

It is guaranteed that the sum of nn over all test cases doesn't exceed 3⋅105.

Output

For each test case, print a single integer  — the maximum possible value of the product from the statement.

思路:一开始搞错了,一直在想怎么弄出区间的最大值和次大值,蠢哭了,后来才想到题目是要求区间最小值和区间最大值的乘积最大值。那其实就是相邻的数乘积求最大值呀。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100010];//maxn[100010],minn[100010];
void solve()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)	cin>>a[i];
	//区间最大值*区间最小值
	ll maxn=0;
	for(int i=1;i<n;i++)
	{
		maxn=max(maxn,a[i]*a[i+1]);
	}
	cout<<maxn<<endl;
	return ;
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
	return 0;
}

Problem - C - Codeforces

You have a string ss consisting of digits from 0 to 9 inclusive. You can perform the following operation any (possibly zero) number of times:

  • You can choose a position ii and delete a digit dd on the ii-th position. Then insert the digit min(d+1,9) on any position (at the beginning, at the end or in between any two adjacent digits).

What is the lexicographically smallest string you can get by performing these operations?

A string aa is lexicographically smaller than a string bb of the same length if and only if the following holds:

  • in the first position where aa and bb differ, the string aa has a smaller digit than the corresponding digit in bb.

Input

The first line contains a single integer tt (1≤t≤104) — the number of test cases. Then the test cases follow.

Each test case consists of a single line that contains one string ss (1≤|s|≤2⋅105) — the string consisting of digits. Please note that ss is just a string consisting of digits, so leading zeros are allowed.

It is guaranteed that the sum of lengths of ss over all test cases does not exceed 2⋅1052⋅105.

Output

Print a single string — the minimum string that is possible to obtain.

这其实是老早之前的一个题目了,一直没去补。

思路:题目意思就是说你每一次操作都可以使得一个字符加一然后插入到字符串的任意位置,最后是的字符串序列最小。要使得字符串序列最小,那肯定是加的少一些会好一些呀,是吧,就尽量把小的字符放在前面。操作次数是无所谓的。

AC题解:

//使得最终序列最小
#include<bits/stdc++.h>
using namespace std;
void solve()
{
    int mp['9'+1]={0};
    string s;
        cin>>s;
        char last=s[s.size()-1];
        string t="";
        for(int i=s.size()-1;i>=0;i--)
        {
            if(s[i]>last)
            {
                s[i]=s[i]+1;
                if(s[i]>'9')    mp['9']++;
                else    mp[s[i]]++;
            }
            else
            {
                mp[s[i]]++;
                last=s[i];
            }
        }
        for(char i='0';i<='9';i++)
            while(mp[i]--)
                t+=i;

        cout<<t<<endl;
}
int main()
{
    int t;
    //ios::sync_with_stdio(false);
    //cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

TLE题解:

//使得最终序列最小
#include<bits/stdc++.h>
using namespace std;
void solve()
{
    int mp['9'+1]={0};
    string s;
        cin>>s;
        char last=s[s.size()-1];
        string t="";
        for(int i=s.size()-1;i>=0;i--)
        {
            if(s[i]>last)
            {
                s[i]=s[i]+1;
                if(s[i]>'9')    mp['9']++;
                else    mp[s[i]]++;
            }
            else
            {
                mp[s[i]]++;
                last=s[i];
            }
        }
        for(char i='0';i<='9';i++)
            while(mp[i]--)
                t=t+i;
        cout<<t<<endl;
}
int main()
{
    int t;
    //ios::sync_with_stdio(false);
    //cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

注意,这两个有什么区别,区别就在于字符串相加的式子不一样,一个是t = t + i ,一个是t + = i ,这是有区别的,详见:C++ 中 string 相加拼接的效率问题_Roger_dai的博客_c++ string 高效拼接

Problem - C - Codeforces

Alice and Bob are playing a game on a sequence a1,a2,…,an of length nn. They move in turns and Alice moves first.

In the turn of each player, he or she should select an integer and remove it from the sequence. The game ends when there is no integer left in the sequence.

Alice wins if the sum of her selected integers is even; otherwise, Bob wins.

Your task is to determine who will win the game, if both players play optimally.

Input

Each test contains multiple test cases. The first line contains an integer tt (1≤t≤100) — the number of test cases. The following lines contain the description of each test case.

The first line of each test case contains an integer n (1≤n≤100), indicating the length of the sequence.

The second line of each test case contains nn integers a1,a2,…,an (−109≤ai≤109), indicating the elements of the sequence.

Output

For each test case, output "Alice" (without quotes) if Alice wins and "Bob" (without quotes) otherwise.

思路:看完之后,可想而知,博弈。那么怎么博弈呀!!!

我决定再写一次:

序列当中,奇数数量为a,偶数数量为b。

if(b%4==2),也就是说b/2%2=1,那么后者就可以一直跟着前面那个人拿,到最后就是每一个人都有奇数个奇数,也就是说,此时,后者稳赢。

if(b%4==3),此时,如果说先手先拿一个奇数,那么此时的情况就等于第一种情况,由上面可知是后手稳赢,那现在就是先手稳赢,因为先手已经拿了一个奇数,刚刚好相加为偶数了,也就是说,此时,先手稳赢。

if(b%4==0),那么,此时,先手先拿一个偶数,那么此时,奇数数量还有偶数个,而且是对半分之后还是偶数,那么此时先手就是跟着后手拿就好了呀,就算是最后一个偶数被后手拿了,那先手先去拿奇数也无所谓,反正最后奇数是对半分的,也就是说,此时,先手稳赢。

if(b%4==1),此时,谁先拿了一个1,也就成了是(b%4==0)的后手了,就输定了,那么我们此时,就是去讨论a的情况了,如果说a%2==1,也就是说,先手是可以拿到最后一个1的,那么先手稳赢;否则就是后手会拿到最后一个1,先手就输了。

//if(b%4==2)
//那么后者可以一直跟着前者拿,就算最后一个0被前者拿了,后面剩下的1肯定是偶数个,也成立
//也就是说,bob稳赢
//if(b%4==3)
//那么前者可以先拿一个1,那么后面剩下的情况就是b&4==2的情况了,也就是说此时的先手会拿到奇数个1,再加上原来的1,就有偶数个
//也就是说,alice稳赢
//if(b%4==0)
//先手先拿一个0,之后就是跟着后手拿就行了,奇数数量是偶数个,必定位偶数
//也就是说alice稳赢 
//if(b%4==1)
//谁拿了一个1之后呢,就是b%4==0的情况了,也就是说是,拿了之后的先手赢
//讨论:谁先去那那个1,如果偶数数量是偶数个,也就是说alice去拿,那么bob赢了
//如果偶数数量为奇数,那么alice赢了 
#include<bits/stdc++.h>
using namespace std;
void solve()
{
	int n;
	cin>>n;
	int a=0;int b=0;
	for(int i=1;i<=n;i++)
	{
		int k;
		cin>>k;
		if(k&1)	b++;
		else	a++;
	}
	if(b%4==2)	cout<<"Bob\n";
	else if(b%4==3)	cout<<"Alice\n";
	else if(b%4==0)	cout<<"Alice\n";
	else
	{
		if(a&1)	cout<<"Alice\n";
		else	cout<<"Bob\n";
	}
	return ;
}
int main()
{
	int t;
	cin>>t;
	while(t--)	solve();
	return 0;
}

Problem - C - Codeforces

There was a string ss which was supposed to be encrypted. For this reason, all 26 lowercase English letters were arranged in a circle in some order, afterwards, each letter in ss was replaced with the one that follows in clockwise order, in that way the string tt was obtained.

You are given a string t. Determine the lexicographically smallest string ss that could be a prototype of the given string t。

A string aa is lexicographically smaller than a string bb of the same length if and only if:

  • in the first position where aa and bb differ, the string aa has a letter, that appears earlier in the alphabet than the corresponding letter in b.

Input

The first line of the input contains a single integer tt (1≤t≤3⋅104) — the number of test cases. The description of test cases follows.

The first line of each test case contains one integer nn (1≤n≤105) — the length of the string tt.

The next line contains the string tt of the length nn, containing lowercase English letters.

It is guaranteed that the sum of nn over all test cases doesn't exceed 2⋅105。

Output

For each test case, output a single line containing the lexicographically smallest string ss which could be a prototype of tt.

题目意思是说需要26个字母成环,只能是26个字母成环。

思路:对于像关系网这样的情况,最好想的就是并查集了,要他们不能成环,也就是说前25个匹配的字母他们的父辈不能是一样的,最后一个字符就直接加进去就好了。

#include<bits/stdc++.h>
using namespace std;
int pre[26],ne[26],f[26];
int n;
string s;
int find(int u)
{
    while(u!=f[u])
        u=f[u];
    return u;
}
//题目含义是说26个小写英文字母要构成一个环,不能够小于26个,
//使用并查集,使得大家在同一个关系网里,且不能够成环
void solve()
{
    cin>>n;
    cin>>s;
    for(int i=0;i<26;i++)
    {
        f[i]=i;
        pre[i]=-1;//pre是指转换之前,就是说谁变为他的
        ne[i]=-1;//ne是指转换之后,他变成谁
    }
    int cnt=1;
    for(int i=0;i<s.size();i++)
    {
        int k=s[i]-'a';
        for(int j=0;j<26;j++)
        {
            if(pre[k]!=-1)    break;
            if(ne[j]!=-1)    continue;
            if(cnt<26)//还有 没有转换的字符
            {
                int tx=find(k);int ty=find(j);//寻找他们的关系网
                if(tx!=ty)//还没有26个,不能够自成环
                {
                    f[tx]=ty;
                    pre[k]=j;
                    ne[j]=k;
                    cnt++;
                    break;//找到之后,就可以退出了
                }
            }
            else
            {
                pre[k]=j;
                ne[j]=k;
                cnt++;
                break;
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        char tmp=pre[s[i]-'a']+'a';
        cout<<tmp;
    }
    cout<<endl;
    return ;
}
int main()
{
    int t;
    cin>>t;
    while(t--)    solve();
    return 0;
}

Problem - B - Codeforces

There are nn pieces of tangerine peel, the ii-th of them has size aiai. In one step it is possible to divide one piece of size xx into two pieces of positive integer sizes y and z so that y+z=x。

You want that for each pair of pieces, their sizes differ strictly less than twice. In other words, there should not be two pieces of size x and y, such that 2x≤y, What is the minimum possible number of steps needed to satisfy the condition?

Input

The first line of the input contains a single integer t (1≤t≤100) — the number of test cases. The description of test cases follows.

The first line of each test case contains the integer n (1≤n≤100).

Then one line follows, containing nn integers a1≤a2≤…≤an(1≤ai≤107).

Output

For each test case, output a single line containing the minimum number of steps.

//两两不超过两倍的关系
#include<bits/stdc++.h>
using namespace std;
void solve()
{
    int n;
    cin>>n;
    int a[110];
    for(int i=1;i<=n;i++)    cin>>a[i];
    //就只对所有的值
    int ans=0;
    a[1]+=a[1];
    for(int i=2;i<=n;i++)
    {
        if(a[1]>a[i])    continue;
        //else if(a[1]==2)    ans=ans+a[i]/(a[1]-1)-1;
        else    
        {
            if(a[i]/(a[1]-1)*(a[1]-1)==a[i])    ans+=a[i]/(a[1]-1)-1;
            else    ans+=a[i]/(a[1]-1);
            
        }
        /*{
            //if(a[1]*2<=a[i])
                ans=ans+a[i]/(2*a[1]-1);
            /*if(a[i]%(2*a[1]-1))    ans++;
            while(a[1]*2<=a[i])
            {
                ans++;
                a[i]=a[i]-(2*a[1]-1);
            }
        }*/
    }
    cout<<ans<<endl;
    return ;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--)    solve();
    return 0;
}

Problem - A - Codeforces

Your working week consists of nn days numbered from 1 to n, after day nn goes day 1 again. And 3 of them are days off. One of the days off is the last day, day n. You have to decide when the other two are.

Choosing days off, you pursue two goals:

  • No two days should go one after the other. Note that you can't make day 1 a day off because it follows day nn.
  • Working segments framed by days off should be as dissimilar as possible in duration. More specifically, if the segments are of size l1, l2, and l3 days long, you want to maximize min(|l1−l2|,|l2−l3|,|l3−l1|),

Output the maximum value of min(|l1−l2|,|l2−l3|,|l3−l1|) that can be obtained.

Input

The first line of the input contains a single integer tt (1≤t≤1000) — the number of test cases. The description of test cases follows.

The only line of each test case contains the integer nn (6≤n≤109).

Output

For each test case, output one integer — the maximum possible obtained value.

就是说最大化最短持续时间,且三个数不同。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        if(n<=7)    cout<<0<<endl;
        else    cout<<(n-3)/3-1<<endl;
    }
    return 0;
}

数学考试 (nowcoder.com)

入门dp题。定义dp[i][j]表示做完第i份作业之后,压力指标为j时,可以积累的最大经验值,

那么就考虑如何使得压力指标在做完第i份作业之后变为j

#include<bits/stdc++.h> //using namespace std; using namespace std; typedef long long ll; #define int long long #define endl "\n" #define pb push_back #define pr pair<int,int> #define all(a) a.begin(),a.end() #define fr first #define se second #define mk make_pair const signed N = 1e6 + 7; const int mod = 1e9 + 7; int f[2][5007]; void solve() { int n, k; cin >> n >> k; for (int i = 1; i <= n; i++) { int no = i & 1; int la = no ^ 1; memset(f[no], 0, sizeof f[no]); int a, b, q, w; cin >> a >> b >> q >> w; for (int j = 0; j <= k; j++) { f[no][j] = max(f[la][j],f[no][j]); //if (i != 1 && !f[la][j]) continue; if (j <= b) f[no][j] = max(f[no][j], f[la][j] + a * j); if (j + q <= k) { if (j <= b) f[no][j + q] = max(f[no][j + q], f[la][j] + a * j); else f[no][j + q] = max(f[no][j + q], f[la][j]); } if (j - w >= 0) { if (j <= b) f[no][j - w] = max(f[no][j - w], f[la][j] + a * j); else f[no][j - w] = max(f[no][j - w], f[la][j]); } } } int no = n & 1; int ans = 0; for (int i = 0; i <= k; i++) ans = max(ans, f[no][i]); cout << ans; } signed main() { cin.sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); } /* 在这里养了一只猫猫,路过的朋友可以摸摸她       />  フ       |  _  _ l       /` ミ_xノ      /      |     /  ヽ   ノ     │  | | |  / ̄|   | | |  | ( ̄ヽ__ヽ_)__)  \二つ */

到这就结束了!!!