Ufpe Starters Final Try-out 2020

question:

Problem - A - Codeforces

Accept or Reject(找字符串中特定长度的字符串,找到accept, or reject)

thought:

通俗的二次Hash函数:hash2(key) = PRIME – (key % PRIME)

PRIME一般选择小于 TABLE_SIZE 的质数

优质的二次Hash函数应该具备这些条件:

  • 二次Hash函数结果不能为0
  • 第二个哈希函数要可以覆盖表的每一个单元
#include <bits/stdc++.h>
using namespace std;

#define db(x) cerr<<#x<<" == "<<x<<endl
#define _ <<", "<<

const int B = 1e9+7;
//const int B = 1;
const int N = 5e5+5;

unsigned long long h[N], r[N];
int n, m;
char s[N];

int main() {
  scanf("%d%d%s", &n, &m, s+1);

  unsigned long long BM = 1;
  for (int i = 0; i < m; i++) BM = B*BM;

  for (int i = 1; i <= n; i++) {
  	h[i] = B*h[i-1] + s[i];
  	//cout << h[i] << " ";
  }
  //cout << endl;
  for (int i = n; i > 0; i--)  {
  	r[i] = B*r[i+1] + s[i];
  	//cout << r[i] << " ";
  }

  for (int i = m; i <= n; i++) {
    if (h[i] - BM*h[i-m] == r[i-m+1] - BM*r[i+1]) {
      printf("Accept\n");
      return 0;
    }
  }

  printf("Reject\n");
  return 0;
}

 question:

Problem - B - Codeforces

Beza's Hangover

简介:

单点修改和区间求和。
问区间和是否大于区间时间值的一半

thought:

 是一道线段树题。

map需要输入后面的m个字符串,不能输入n个字符串,而不是。因为前面的n个字符不一定包含了所有种类。

#include <bits/stdc++.h>
 
using namespace std;
 
const int maxn =2e5+100;
int a[maxn];
int tree[maxn*4];
int n,m,k;
map<string,int>mp;
char s[maxn][22];
void build(int l,int r,int node)
{
    if(l==r)
    {
        tree[node]=a[l];
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,node*2);
    build(mid+1,r,node*2+1);
    tree[node]=tree[node*2]+tree[node*2+1];
}
void updata(int node,int l,int r,int x,int y)
{
    if(l==r)
    {
        tree[node]=y;
        return ;
    }
    int mid=(l+r)/2;
    if(x<=mid)
    {
        updata(node*2,l,mid,x,y);
    }
    if(x>mid)
    {
        updata(node*2+1,mid+1,r,x,y);
    }
    tree[node]=tree[node*2]+tree[node*2+1];
}
int query(int node,int l,int r,int x,int y)
{
    if(l>=x&&r<=y)
    {
        return tree[node];
    }
    int mid=(l+r)/2;
    int res=0;
    if(x<=mid)
    {
        res+=query(node*2,l,mid,x,y);
    }
    if(y>mid)
    {
        res+=query(node*2+1,mid+1,r,x,y);
    }
    return res;
}
int main()
{
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<n;i++)
    {
        scanf("%s",s[i]);
    }
    char str[maxn];
    int x;
    while(m--)
    {
        scanf("%s%d",str,&x);
        mp[str]=x;
//        cout<<mp[str]<<" "<<str<<endl;
    }
    for(int i=1;i<=n;i++)
    {
        a[i]=mp[s[i-1]];
//        cout<<s[i-1]<<" "<<mp[s[i-1]]<<endl;
//        cout<<a[i]<<" "<<s[i-1]<<endl;
    }
//    cout<<endl;
    build(1,n,1);
    int u,v,w;
    while(k--)
    {
        scanf("%d",&u);
        if(u==1)
        {
            scanf("%d",&v);
            scanf("%s",str);
            updata(1,1,n,v,mp[str]);
        }
        else
        {
            scanf("%d%d",&v,&w);
            int ans=query(1,1,n,v,w);
//            printf("%d\n",ans);
            if(ans>(w-v+1)*30) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}

 

question:

Problem - G - Codeforces

Gorggeous Peter's Great Friend(找到对应的人和题答对得分) 

thought:
①先想着用类来写,超时了,查找到结构体和类的区别:

1.  堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些
2.   结构表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低
3.  在表现抽象和多级别的对象层次时,类是最好的选择
4.  大多数情况下该类型只是一些数据时,结构时最佳的选择 

②在c++中用scanf读string要带上对象的首地址,因为string 在c++中是类的形式存在的不能直接读(gnl)

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

int C, S, P;
string tmp;
struct node {
    string name;
    int s;
}ha[MAXN];
map <string, int> handle; 
map <string, int> prob;//时间会短 

int main() {
    scanf("%d%d%d", &C, &P, &S);
    for(int i = 1; i <= C; i++) {
        cin >> tmp;
        handle[tmp] = i;//用string与int 绑定 
        ha[i].name = tmp;
    }
    for(int i = 1; i <= P; i++) {
        int x;
        cin >> tmp >> x;
        prob[tmp] = x;
    }
    while(S--) {
        string s1, s2, s3;
        cin >> s1 >> s2 >> s3;
        if(s3 == "AC") ha[handle[s1]].s += prob[s2];
    }
    for(int i = 1; i <= C; i++) {
        cout << ha[i].name << " " << ha[i].s << endl;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SUGA no sugar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值