L、Problem L is the Only Lovely Problem

签到题,字符串处理,注意不区分大小写就是了。

s = input().lower()
if len(s)<6:
    print('ugly')
else:
    if s[:6] == 'lovely':
        print('lovely')
    else:
        print('ugly')

B、Classical String Problem

给出一个起始字符串,n次操作,一种是修改,正数就从前面x个字符串分隔整体换位置。
一种是查询,问当前操作中的字符串第x个字符是什么,下标1开始,输入均合法。
解题思路:抓住分隔整体换位置这个要点,最开始写的python字符串切片取硬模拟,果不其然的TLE了。
那么模拟不行,换个办法?整体分隔,再换位置,你会发现,只有起始的头下标变了,n后面接着还是1,1后面接2。
如果你再换,把2换到开头,1过了还是2,2过了就是3,无论怎么写样例你会发现,只有开头在动,整体字符串的相对位置都是保持不动的。
得出这个结论的要点在于整体移动不改变相对性。这样的话就会有一种O(T)的做法,直接取模维护起点下标既可。
使用cin记得关掉和scanf的兼容)巨量数据建议还是putchar什么的。

#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math")
#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define all(__vv__) (__vv__).begin(), (__vv__).end()
#define endl "\n"
#define pai pair<int, int>
#define mk(__x__,__y__) make_pair(__x__,__y__)
#define ms(__x__,__val__) memset(__x__, __val__, sizeof(__x__))
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar())    s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void print(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-');    int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';        tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;    while (b) { if (b & 1)    ans *= a;        b >>= 1;        a *= a; }    return ans; }    ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
inline int lowbit(int x) { return x & (-x); }

const int N = 1e5 + 7;
string s;
int main() {
    js;
    int T, x, st = 0;
    cin >> s >> T;
    int len = s.size();
    while (T--) {
        char op;
        cin >> op >> x;
        if (op == 'A')    cout << s[(st + x - 1) % len] << endl;
        else    st = (st + x + len) % len; //记录开头的下标即可
    }
    return 0;
}

A、Clam and Fish

队友切掉的)队友太顶了
题目描述大概是,有四种模式,分别是

0代表的没鱼没蚯蚓
1代表的没鱼有蚯蚓
2代表的有鱼没蚯蚓
3代表的有鱼有蚯蚓

下面给出你的每一步模式,如果这一步选择了捕鱼可以直接鱼数目加1,否则蚯蚓可以花费一个回合做成鱼饵,如果这个回合没有鱼但是你手上有鱼饵的话,还是可以让你的鱼数目加1。
问题:如何再给定每天模式的情况下,让最后一天钓上来的鱼数目最多。

解题思路:首先是一个最基本的贪心思路,我们需要得到最多的鱼,这一天如果是2,3两种状态的话,肯定想也不想直接捕鱼,2不多说,3的话你做鱼饵再钓鱼用2天时间,肯定比不上你这一天直接钓鱼来的实在。也就是满足了我现在的选择肯定不会比别的选择差这一条贪心策略。
剩下就是0,1两种模式,0的话肯定也不多说,直接由鱼饵就钓鱼,没有就空过,关键在于1状态如何处理让答案最大。
我们可以统计出后一天开始没有鱼钓的天数,如果现在拥有的鱼饵数大于等于后一天开始没有鱼钓天数,说明现在继续囤积鱼饵也用不出去,这天选择用掉鱼饵,但是如果我当前的鱼饵数不够后一天开始没有鱼钓的天数,那我就现在开始尽可能多的囤积鱼饵,反正在后续的天数内,上钓的鱼数目是相同的,也满足了贪心中最起码不必别人差的策略。
那么最后还要统计出后一天到最后没有鱼掉的天数,可以用倒序遍历方法,求个后缀和就行。

不得不说是一个很好的贪心题目,好在队友想到解决方法了。

#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline void write(__int128 x) { if (!x) { putchar('0'); return; } char F[50]; __int128 tmp = x > 0 ? x : -x; if (x < 0)putchar('-');  int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';     tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
#define pb push_back
#define pll pair<ll,ll>
#define INF 0x3f3f3f3f
const int mod = 1e9+7;
const int maxn = 55;
#define stop system("pause")
#define PI acos(-1.0)
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
int num[2000005];
char s[2000005];
int main(){
    int t = read();
    while(t--){
        int n = read();
        scanf("%s",s);
        int ans = 0,yue = 0;
        num[n] = 0;
        for(int i = n-1 ; i >=0 ; --i){
            if(s[i] =='1' ||s[i] == '0') num[i] = num[i+1] +1;
            else num[i] = num[i+1];
        }
        for(int i = 0 ; i < n ; ++i){
            if( s[i] == '0' && yue) ++ans,--yue;
            else if(s[i] == '1'){
                if(yue > 0 && yue >= num[i+1]) --yue,++ans; //注意细节,别出-1的鱼饵数了
                else ++yue;
            }
            else if(s[i] == '2' || s[i] == '3') ++ans;
        }
        printf("%d\n",ans);
    }
}

C、Operation Love

给出20个二维平面的点,可能是浮点数,但是顺序或者倒序连接之后一定是图中左手或者右手的图案。
并且保证,图形只做旋转和平移,不做放缩处理。
需要我们判断他给出的图像是左手还是右手?

解题思路:通过向量的叉乘判断顺逆时针,这个题目我觉得难点就这一个)如果除开精度来说的话……1e-6卡了3下,1e-2就A了
如果你判断出了顺逆时针,那么我还多写了一步,把长度复制一倍,怕他给出的起点不是最左下的点或者最右下的点。
这样连接之后,求下两两之间的距离,找出最长的9所在下标,直接判断顺时针下9下一条边应该长度为几,就可以出左右手了,逆时针同理。

具体判断三点的顺逆性可以去百度,公式也很简单)不记得寒假那本算法书讲过,使用有点印象就写出这题来了。

#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math")
#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define all(__vv__) (__vv__).begin(), (__vv__).end()
#define endl "\n"
#define pai pair<double, double>
#define mk(__x__,__y__) make_pair(__x__,__y__)
#define ms(__x__,__val__) memset(__x__, __val__, sizeof(__x__))
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar())    s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void print(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-');  int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';     tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll qpow(ll a, ll b) { ll ans = 1;   while (b) { if (b & 1)  ans *= a;       b >>= 1;      a *= a; }   return ans; }   ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; }
inline int lowbit(int x) { return x & (-x); }

const int N = 50;
const double eps = 1e-2;
pai a[N];
#define x first
#define y second
struct Node {
    int dis;
    int id;
    bool operator < (const Node& A) const {
        if (dis != A.dis)   return dis > A.dis;
        return  id > A.id;
    }
}b[N];

int main() {
    js;
    int T;  cin >> T;
    while (T--) {
        for (int i = 1; i <= 20; ++i) {
            cin >> a[i].x >> a[i].y;
            a[20 + i] = a[i];
        }
        for (int i = 2; i <= 40; ++i) {
            b[i].dis = fabs(sqrt((a[i].x - a[i - 1].x) * (a[i].x - a[i - 1].x) + (a[i].y - a[i - 1].y) * (a[i].y - a[i - 1].y))) + eps;
            b[i].id = i;
        }
        int cnt = 0, pos = -1;
        for (int i = 2; i <= 40; ++i) {
            if (b[i].dis == 9) {
                pos = i;
                break;
            }
        }
        int flag = 0;
        if ((a[pos].x - a[pos - 1].x) * (a[pos + 1].y - a[pos].y) - (a[pos + 1].x - a[pos].x) * (a[pos].y - a[pos - 1].y) < 0) { //向量叉乘,小于零顺时针
            flag = 1;
        }
        //否则逆时针
        if (flag) {
            if (b[pos + 1].dis == 6)    cout << "right" << endl;
            else cout << "left" << endl;
        }
        else {
            if (b[pos + 1].dis == 6)    cout << "left" << endl;
            else cout << "right" << endl;
        }
    }
    return 0;
}