第七周周四总结

  星期一到现在一共做了四道题吧,提交了三道,只过了两道,还一道没调出来。。。上课了空闲时间有点少吧


Who Gets the Most Candies?

Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 262144/131072K (Java/Other)
Total Submission(s) : 43   Accepted Submission(s) : 17
Problem Description

N children are sitting in a circle to play a game.

The children are numbered from 1 to N in clockwise order. Each of them has a card with a non-zero integer on it in his/her hand. The game starts from the K-th child, who tells all the others the integer on his card and jumps out of the circle. The integer on his card tells the next child to jump out. Let A denote the integer. If A is positive, the next child will be the A-th child to the left. If A is negative, the next child will be the (A)-th child to the right.

The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F(p) candies where F(p) is the number of positive integers that perfectly divide p. Who gets the most candies?

 

Input
There are several test cases in the input. Each test case starts with two integers <i>N</i> (0 < <i>N</i> <span lang="en-us">≤ 500,000) and <i>K</i> (1 ≤ <i>K</i> ≤ <i>N</i>) on the first line. The next <i>N</i> lines contains the names of the children (consisting of at most 10 letters) and the integers (non-zero with magnitudes within 10<sup>8</sup>) on their cards in increasing order of the children’</span>s numbers, a name and an integer separated by a single space in a line with no leading or trailing spaces.
 

Output
<p>Output one line for each test case containing the name of the luckiest child and the number of candies he/she gets. If ties occur, always choose the child who jumps out of the circle first.</p>
 

Sample Input
  
  
4 2 Tom 2 Jack 4 Mary -1 Sam 1
 

Sample Output
  
  
Sam 3
 
题意:这道题的题意和以前做过的一道题差不多,给你n个人的名字和权值,然后从第k个人开始离开队伍,如果他的权值是正就顺时针找第权值个人,否则就逆时针,如果他是第A个出去的,那么得到的糖果数目为A能被多少个整数整除的数目,例如第四个离开, 能被1、2、4整除,那么就得到3个糖果。

而这儿整除的数目我本想for循环找的,然后搜了下是反素数,又学到了0.0,就直接借鉴了大佬们的部分代码。


#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int n,k;
int s[500005],f,ss;
struct Name
{
char name[11];
int v;
}a[500005];
struct F
{
int l,r,sum;
}tree[2000005];
void build(int l,int r,int p)
{
tree[p].l=l;
tree[p].r=r;
tree[p].sum=r-l+1;
if(l==r)
    return;
int mid=(l+r)/2;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
}
int find(int rt,int p)
{
tree[p].sum--;
if(tree[p].l==tree[p].r)
    return tree[p].l;
if(rt<=tree[p*2].sum)
    find(rt,p*2);
else
    find(rt-tree[p*2].sum,p*2+1);
}
int main()
{
int i,j;
while(cin>>n>>k)
    {
    for(i=1;i<=n;i++)
        scanf("%s%d",a[i].name,&a[i].v);
    build(1,n,1);
    memset(s,0,sizeof(s));
    for(i=1;i<=n;i++)
        {
        s[i]++;
        for(j=i*2;j<=n;j+=i)
            s[j]++;
        }
    ss=s[1],f=1;
    for(i=2;i<=n;i++)
        if(ss<s[i])
        {
        ss=s[i];
        f=i;
        }
    int ff=f,q;
    for(i=0;i<ff;i++)
        {
        n--;
        q=find(k,1);
        if(n==0)
            break;
        if(a[q].v>0)
            k=(k+a[q].v-2)%n+1;
        else
            k=((k+a[q].v-1)%n+n)%n+1;

        }
    printf("%s %d\n",a[q].name,ss);
    }
}


Problem M
Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 33   Accepted Submission(s) : 23
Problem Description
There are n men ,every man has an ID(1..n).their ID is unique. Whose ID is i and i-1 are friends, Whose ID is i and i+1 are friends. These n men stand in line. Now we select an interval of men to make some group. K men in a group can create K*K value. The value of an interval is sum of these value of groups. The people of same group's id must be continuous. Now we chose an interval of men and want to know there should be how many groups so the value of interval is max.
 

Input
First line is T indicate the case number. For each case first line is n, m(1<=n ,m<=100000) indicate there are n men and m query. Then a line have n number indicate the ID of men from left to right. Next m line each line has two number L,R(1<=L<=R<=n),mean we want to know the answer of [L,R].
 

Output
For every query output a number indicate there should be how many group so that the sum of value is max.
 

Sample Input
   
   
1 5 2 3 1 2 5 4 1 5 2 4
 

Sample Output
   
   
1 2

题意:给你一个数列,再给你区间,然后如果区间其中的数是挨着的话那么就能构成一个新的数组,问能构成几个数组也就是又多少段连续数。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct f
{
int l,r,p;
}tree[100005];
int ss[100005],c[100005],a[100005],b[100005],n;
bool cmp(f aa,f bb)
{
return aa.r<bb.r;
}
int lowbit(int aa)
{
return aa&(-aa);
}
void add(int p,int v)
{
while(p<=n)
    {
    c[p]+=v;
    p+=lowbit(p);
    }
}
int sum(int p)
{
int s=0;
while(p>0)
    {
    s+=c[p];
    p-=lowbit(p);
    }
return s;
}
int main()
{
int t,i,j,f,m;
scanf("%d",&t);
while(t--)
    {
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        {
        scanf("%d",&a[i]);
        b[a[i]]=i;
        }
    for(i=0;i<m;i++)
        {
        scanf("%d%d",&tree[i].l,&tree[i].r);
        tree[i].p=i;
        }
    sort(tree,tree+m,cmp);
    memset(c,0,sizeof(c));
    f=0;
    for(i=1;i<=n;i++)
        {
        add(i,1);
        if(a[i]>1&&b[a[i]-1]<i)
            add(b[a[i]-1],-1);
        if(a[i]<n&&b[a[i]+1]<i)
            add(b[a[i]+1],-1);
        while(f<m&&tree[f].r==i)
            {
            ss[tree[f].p]=sum(tree[f].r)-sum(tree[f].l-1);
            f++;
            }
        }
    for(i=0;i<m;i++)
        printf("%d\n",ss[i]);
    }
return 0;
}

还有1014题,今天上实验课的时候看了看这道题,感觉不用线段树就可以,然后写了下,没过,明天再试下,再过不了再用线段树,看了下大佬们的题解,是从后往前,而我是从前我往后,我是想先排序左边界,然后这一点与后面就会有6种情况,然后每种情况讨论,然后查看是否该段能否被覆盖,不过也许会超时,不过总得试过了才知道。。。


  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值