题解

这是某场cf,div3中的一些题,思路不止一种,仅供参考

A:   

//思路:如果sum%2==1或者数组中奇数的个数和偶数的个数都大于等于1就是YES。其余的为NO。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<string>
#include<algorithm>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int u=0,v=0;
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            sum+=x;
            if(x%2==0)
                v=1;
            else
                u=1;
        }
        if(sum%2==0&&u+v<2)
            printf("NO
");
        else
            printf("YES
");
    }
}

B:

//你有n元,你买x元东西就会返现x/10元,百度翻译说是四舍五入,但根据样例就会知道是整数除,每次都买10的倍数的东西,直到钱少于10块就可以了。
#include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<string> #include<algorithm> #include<queue> #include<map> typedef long long ll; using namespace std; int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int sum=0; while(n>=10) { int x=n/10; sum=sum+x*10; n=x+n%10; } sum+=n; printf("%d ",sum); } }

C:

//题意:
//给一个字符串,每种字符都代表一个坐标变换,让求删除一个最短的子串(不为空)使得删除这个子串后最终坐标点位置不变,找到了输出子串的起始位置和结束位置,
//若找不出这样一个子串,那么输出-1,字符串下标从1~n。
//思路:
//记录某个坐标点上一次出现的时间,肯定得想到用map。
#include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<string> #include<algorithm> #include<queue> #include<map> typedef long long ll; using namespace std; char a[200005]; int main() { int t; scanf("%d",&t); while(t--) { map<int,map<int,int> >mp; int n; scanf("%d",&n); scanf("%s",a+1); int l,r;//记录所删除子串的左右端点 int x=0,y=0;//记录点的坐标 int mi=n+2;//删除的最小长度 for(int i=1; i<=n; i++) { if(a[i]=='L') x--; else if(a[i]=='R') x++; else if(a[i]=='U') y++; else if(a[i]=='D') y--; if(x==y&&x==0)//map的初始值都为0,而机器人第一次出现在(0,0)位置是0时刻,所以不好记录,就特判下 { if(mi>i) { mi=i; l=0; r=i; } } if(mi>i-mp[x][y]&&mp[x][y]!=0)//更新最小子串 { mi=i-mp[x][y]; l=mp[x][y]; r=i; } mp[x][y]=i;//更新这个位置出现的时间 } if(mi==n+2)//无法删除 printf("-1 "); else printf("%d %d ",l+1,r); } }

D:

//题意:
//有n只怪兽,每只怪兽的血量为s[i],你的攻击力为a,敌人的攻击力为b,对于每只怪兽你和你的敌人轮流进行攻击(你先攻击),如果这只怪兽是被你打死的就获得1分,
//现在你有某种办法让敌人跳过他的回合,但这只能使用 k次,现在问你最多能获得多少分
//思路:
//贪心,对于每只怪兽分别计算出至少要跳过对手多少个回合才是由你打死这只怪兽的,然后从小到大排序进行贪心就可以了。
#include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<string> #include<algorithm> #include<queue> #include<map> typedef long long ll; using namespace std; int s[200005],w[200005]; int main() { int n,a,b,k; scanf("%d%d%d%d",&n,&a,&b,&k); for(int i=1;i<=n;i++) scanf("%d",&s[i]); for(int i=1;i<=n;i++) { //int x=a+b; int y=s[i]%(a+b); if(y>0&&y<=a) w[i]=0; else { int z; if(y==0) z=b; else z=y-a; w[i]=z/a; if(z%a!=0) w[i]++; } } sort(w+1,w+n+1); int sum=0; for(int i=1;i<=n;i++) { if(k>=w[i]) { k-=w[i]; sum=i; } else break; } printf("%d ",sum); }

E:

//题意:
//给你一个字符串,让你给每个字符涂色,相邻字符且颜色不同的可以进行交换位置,现在让你用尽可能少的颜色种数,使字符串涂色完后进行一些交换操作使字符串变成升序,
//输出最少的颜色种数已经每个字符的颜色。
//思路:
//从后往前遍历,如果是降序,那该字符的颜色为1,如果不是,那这个字符的颜色为book[a[i]](book数组是记录不成立时每个字符串的颜色),对于比a[i]大的字符,
//book值也肯定至少要比book[a[i]]大1才能使那个字符涂完色交换后在字符a[i]的后面,然后更新比a[i]大的字符的book值。讲的不清楚,但不知道咋说,不懂的话就找找其他
//博客看看,思路也不止一种。
#include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<string> #include<algorithm> #include<queue> #include<map> typedef long long ll; using namespace std; char a[200005]; int b[200005],book[300]; int main() { int n; scanf("%d",&n); scanf("%s",a); for(int i='a';i<='z';i++) book[i]=2; char c='z'; int ma=1; for(int i=n-1;i>=0;i--) { if(a[i]<=c) { b[i]=1; c=a[i]; continue; } b[i]=book[a[i]]; ma=max(ma,b[i]); for(int j=a[i]+1;j<='z';j++) book[j]=max(book[j],book[a[i]]+1); } printf("%d ",ma); for(int i=0;i<n-1;i++) printf("%d ",b[i]); printf("%d ",b[n-1]); }
原文地址:https://www.cnblogs.com/zcb123456789/p/12487766.html