2019NYIST计科第七次周赛总结


秤取物体重量( 二进制枚举法)


nyoj动物统计(字符串操作)

Description 可以用字典树来写哟! 在美丽大兴安岭原始森林中存在数量繁多的物种,在勘察员带来的各种动物

资料中有未统计数量的原始动物的名单。科学家想判断这片森林中哪种动物 的数量最多,但是由于数据太过庞大,科学家终于忍受不了,想请聪明如你

的ACMer来帮忙。

Input 第一行输入动物名字的数量N(1<= N <=

1000),接下来的N行输入N个字符串表示动物的名字(字符串的长度不超过20,字符串全为小写字母,并且只有一组测试数据)。

Output 输出这些动物中最多的动物的名字与数量,并用空格隔开(数据保证最多的动物不会出现两种以上)。

Sample Input 1

10
boar
pig
sheep
gazelle
sheep
sheep
alpaca
alpaca
marmot
mole
Sample Output 1
sheep 3

思路如下:这一题的数据范围不是很大,我们可以用暴力的方法统计处各个动物出现的次数。为了偷懒我们可以用map容器去解决这个问提 我们把动物的名字的作为键,把出现的次数作为值,在循环输入的时候,用find函数其查找map中是否已经,有着这个动物,如果有 map的的值就加1,否则在map 添加 该动物的名字 并把值设为 1


题解如下

#include<iostream>
#include<string>
#include<map>
#include<algorithm>
#include<string.h> using namespace std;
/*
struct MyCmp {
bool operator()(string l, string r) const { return strcasecmp(l.c_str(), r.c_str()) < 0; }
};
*/ //一个自定义map 键 排序函数的范例!!!
int main()
{
int n;
cin>>n;
map<string,int,MyCmp> mp; //实例化map对象
for(int i = 0;i < n;i++)
{
string str;
cin>>str;
if(mp.find(str) == mp.end())
{
mp[str] = 1;
}
else
mp[str]++;
}
int max = 0; string st;
for(map<string,int,MyCmp>::iterator it = mp.begin();it != mp.end();it ++)
{
if(max < it->second)
{
max = it->second;
st = it->first;
}
}
cout<<st<<" "<<max<<endl;
return 0;
}

奥里给!

Description yzj学长听说学弟们觉得题太简单了,所以就出一个稍微有一丢丢难度的题来考考你们!

ACM工作室有n名队员和k个团队。每个队员都是某个团队的成员。所有团队的编号从1到k。现在你将获得一个编号t1、t2、…、tn的数组,其中ti是第i个员工的团队编号。

现在ACM工作室要集体去吃大餐,所以要租一辆容量为s的车,这个s可以任意的,但是容量为s的车最多只能上两个团队,如果上了三个团队,这三个团队将会因为yzj

学长打起来。由于我们是聪明的acmer,所以yzj学长想知道把所有团队都带到目的地的最小花费是多少?花费等于容量乘以乘车次数

注:

1:只能租一辆车

2:每次上车必须是一个团队一个团队的上,不能把一个团队的人拆开

Input

第一行包含两个整数n和k(1≤n≤5⋅10^5,1≤k≤8000)ACM工作室的队员数量和团队数量。第二行包含一个整数序列t1、t2、…、tn,其中ti(1≤ti≤k)是第i个队员的组号。每个团队至少包含一名队员。

Output 输出最小花费即可


思路如下:

这一题就是暴力求解,但是暴力也需要一点技巧,首先我们可以用一个for循环去 车的容量取值范围,然后再用两次嵌套循环,去求 对每一种 容量的车所需要的话费,求解

题解如下

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std; const int LEN = 5e5 + 10;
int main()
{
int n,k;
cin>>n>>k;
int ar[8005] = {0};
int temp;
for(int i = 1;i <= n;i ++)
{
cin>>temp;
ar[temp]++;
}
sort(ar+1,ar+k+1,greater<int>());
int maxx = -1;
//获取 同时乘坐两个队伍需要的 最大容量maxx
for(int i = 1,j = k;i <= j;i++,j--)
{
if(i < j)
maxx = max(ar[i] + ar[j],maxx);
else
maxx = max(maxx,ar[i]);
}
//开始暴力枚举从容量为 ar[0]~maxx之间的所有情况(中间需经过 贪心优化同时乘坐的是那两个队伍) 耗费的话费,并最终找到最小花费
long long ans = 1e18; //存储当前情况的最小花费
for(long long int a = ar[1];a <= maxx;a++)
{
int times = 0,b = 1,c = k;
while(b <= c) //⚠️ 这里是 <= 符号 , 这个while循环表示 循环times次,就要 就要用车 运送 tiems次
{
times ++;
if(b < c&&(ar[b] + ar[c] <= a))
{
b++,c--;
}
else
{
b++;
}
}
ans = min(ans,times*a);
}
cout<<ans; return 0;
}

0和1

Description lsz喜欢二进制字符串(只包含’ 0’和’

1’的字符串)。而且他更喜欢“相等的二进制字符串”,其中‘0’和‘1’的数量是相等的。

lsz希望从原始字符串t中选择一个子字符串,使其成为长度尽可能最长的“相等的二进制字符串”。

lsz还希望从原始字符串t中选择一个子序列,使其成为长度尽可能最长的“相等的二进制字符串。

Input 第一行一个n(1<=n<100000),第二行是一个n长度的二进制字符串

Output 用空格分开的两个数

第一个是子串尽可能最长的“相等的二进制字符串”的长度,第二个是和子序列尽可能最长的“相等的二进制字符串”的长度

Sample Input 1

 8 01001001
Sample Output 1
4 6

Hint 为了防止有人不知道子串和子序列的区别,特意在这里提一下:

对于123456这个字符串

子串:必须在原字符串中是相邻的,比如它的子串有23、345、123456

子序列:在原序列中不必相邻,但是必须保证是原来的顺序,比如子序列有134、146

思路如下: 这一题我们可以把字符串中的0看作是1,1看作是-1,这样我们把前缀和加起来,当某一个未知的前缀和 与 之前某个位置的前缀和相同的时候两个未知之间的子序列0与1数量相同 或者 某个位置某个前缀和的值为0时则从开头为位置到当前位置的0与1的数量相同

题解如下:

#include<iostream>
#include<cmath>
using namespace std; const int LEN = 1e5+10;
int main()
{
int n;
cin>>n;
char ar[n];
cin>>ar;
int count_0=0,count_1=0;
int sum = 0; //求前缀和
int ans = 0;
int pre_sum[2*LEN] = {0}; //这个是用来存储,前缀最大和出现的情况,有点桶排的思想存储某种情况是否出现过
for(int i = 0;i < n;i ++)
{
if(ar[i] == '0') count_0++,sum+=1; //在这里我们默认 如果某一位是0 前缀和就+1,否则减1;
else count_1++,sum-=1; if(sum == 0) //如果sum的值为0,则前字符数组ar的前i个字符中 0与1的数量一定相同
{
if(ans < i)
ans = i;
continue;
}
if(pre_sum[sum+n] == 0) pre_sum[sum+n] = i; //我们 把得到的前缀和sum加上n 这样就不会出现下表为负值的情况,当该if语句成立的时候说明 这个sum值是第一次出现
//如果pre_sum[sum+n] == 0 说明这种情况还没有出现过,则我们就把 首次出现的这个前缀和 sum的位置存储起来
else if(i - pre_sum[sum+n] > ans) //否则这种情况前缀和sum已经出现过了,这个时候那这个前缀和的出现的位置 和 第一次的出现这个前缀和的位置 进行相减得到 0与1相同的一个连续字符串
ans = i - pre_sum[sum+n];
}
cout<<ans<<" "<<min(count_1,count_0)*2; return 0;
}

low || high

Description

p序列是一种整数序列p=[p1,p2,…,pn],这种序列包含n个在1到n之间的不同(唯一)的正整数。例如,下面的序列是p序列:[3,4,1,2],[1],[1,2]。以下序列不是p序列:[0],[1,2,1],[2,3],[0,1,2]。

你现在知道一个p序列的前缀最大值的数组q。

q1=p1, q2=max(p1,p2) q3=max(p1,p2,p3) … qn=max(p1,p2,…,pn)

问满足前缀最大值数组为q的p序列有多少种。(结果可能会很大,输出结果取余1000000007后的值)

Input 第一行包含整数t(1≤t≤10)——输入的测试用例的数量。

每个测试用例的第一行包含一个整数n(1≤n≤1e6)——数组q的长度。

测试用例的第二行包含n个整数q1,q2,…,qn(1≤qi≤n)——数组q的元素,保证所有qi≤qi+1(1<=i<n)

Output 每个测试样例输出一个数,表示满足前缀最大值数组为q的p序列的种数。(结果可能会很大,输出结果取余1000000007后的值)

Sample Input 1

4
5
1 2 3 4 5
5
2 3 4 4 5
5
3 3 5 5 5
5
2 2 2 5 5
Sample Output 1
1
1
4
0

思路如下: 根据前缀最大和的性质,一个数第一次出现的位置就是,它在原来的p序列的位置,而重复出现的位置则是,则是一定是比该重复数小的切还没有出现过的数字,因此我们可以从左到右遍历q序列,遇到第一次出现的,就将它填入p序列,遇到重复就选择一个比它小的填入p序列,根据 排列知识求出方案数。

题解如下:

#include<iostream>
using namespace std; #define max(a,b) (a>b?a:b)
const int mod = 1000000007;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
long long int ans = 1,sum = 0,now,befor = 0; //befor表示前一次输入的值,刚开始给befor不可能去到的值
for(int i = 1;i <= n;i ++)
{
scanf("%lld",&now);
if(now > befor) //条件成立则说明该值now 与前一个值befor不同,直接放入p序列
sum += now - befor -1; //统计这是 在这之前有多少个没有出现过的数字
else
{
ans = (ans * sum--) % mod; //如果相同则从sum个数字中选一个数字放入该位置,此时方案数位ans*=sum
}
befor = now; //更新befor的值
}
printf("%lld\n",max(ans,0));
}
return 0;
}

So easy

Description lsz学长最近迷上了一个叫做lkwg的游戏,他发现一个宠物受到不同的技能伤害后会增加不同的捕捉几率,现在lsz学长

特别想要获得这个宠物,但是他十分纠结他能否获得它。lsz学长可以确定如果你把这个宠物的捕捉几率提升到k及k以上

的时候,lsz学长就可以捕捉到它。lsz学长现在心急如焚,所以想请聪明的你帮忙解决问题(强制性的)!

Input

宠物最初捕捉几率为0,第一行输入两个数n、k,代表有n个技能,k如题意。第二行是n个用空格分隔的数,分别代表每一个技能能使用多少次

第三行也是n个用空格分隔的数,代表每一个技能可以增加多少捕捉几率

第四行还是n个用空格分隔的数,代表每一个技能的代价

Output 如果可以捕捉输出最小的代价

否则输出NO

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

题解如下:

#include<iostream>
using namespace std; int A[15],B[15],C[15];
int n,k; int min_spent = 1e9;
void dfs(int level,int chance,int spent)
{ //level第几个技能,chance捕捉概率,捕捉花费
if(spent >= min_spent || level > n)
return;
if(chance >= k)
{
min_spent = spent;
return;
}
for(int i = 0;i <= A[level];i ++)
{
dfs(level+1,chance + i*B[level],spent + i*C[level]);
}
} int main()
{
cin>>n>>k;
int sum = 0;
for(int i = 0;i < n;i++)
cin>>A[i];
for(int i = 0;i < n;i++)
{
cin>>B[i];
sum += A[i]*B[i];
}
for(int i = 0;i < n;i++)
cin>>C[i];
if(sum < k)
{
cout<<"NO";
}
else
{
dfs(0,0,0);
cout<<min_spent;
}
return 0;
}

奇偶交换

Description

LSZ学长喜欢将奇数和偶数交换,于是就想考大家一个问题。给你一个很大的数n,(0<=n<=10^100),如果这个数的位数中相邻位置的数是一奇一偶的情况下,就可以交换这两个位置上的数,你可以进行无数次的操作,LSZ想让你求出操作后可以达到的最小的值,如果有前导0的情况把前导零输出

Input t组输入(0<t<100),每组输入一个数n,(0<=n<=10^100)

Output 输出操作后的最小的数

Sample Input 1

3
0709
1337
246432
Sample Output 1
0079
1337
234642

Hint 第一个输入的样例中,输入的第一个数0709你可以交换相邻位置的的0(偶数)和7(奇数)然后变成0079此时这个数最小

思路如下: 对于字符串中的每一个数字如果是偶数(奇数)的话无路他怎么变换,它相对其它偶数(奇数)的位置是不会改变的,所以我们可以把奇偶数单独分离开(顺序不变),在奇偶数之间进行比较,把小的放前边,这题的一个比较也是一个难点,这时候的比较我们可以用两个指针来实现比较操作

题解如下

#include<iostream>
#include<string> using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
string str;
cin>>str;
int even[1000];
int odd[1000];
int pos_even = 0;
int pos_odd = 0;
for(int i=0;i<str.size();i++)
if((str[i]-'0')%2 == 0)
even[pos_even++] = str[i] - '0';
else
odd[pos_odd++] = str[i] - '0';
if(pos_even == 0)
{
for(int i=0;i<pos_odd;i++)
cout<<odd[i];
}
else if(pos_odd == 0)
{
for(int i=0;i<pos_even;i++)
cout<<even[i];
}
else
{
int *p_odd = &odd[0],*p_even = &even[0];
while(p_odd != &odd[pos_odd] && p_even != & even[pos_even])
{
if(*p_odd < *p_even)
{
cout<<*p_odd;
p_odd++;
}
else
{
cout<<*p_even;
p_even++;
} }
if(p_odd != &odd[pos_odd])
{
while(p_odd != &odd[pos_odd])
{
cout<<*p_odd;
p_odd++; }
}
else
{
while(p_even != &even[pos_even])
{
cout<<*p_even;
p_even++;
}
}
}
cout<<endl;
}
return 0;
}

聚餐

Description

众所周知ACM工作室有一个传统,就是每年大三大四的学长学姐会请大一大二的吃饭,在聚餐的时候每个人都有一个独特的编号,编号为1~n(1<n<32768),LSZ的编号为n,如果和LSZ是同一届的,那么他的编号和LSZ的编号有大于1的公约数,否则都是不和他一届的,LSZ想知道有多少人和他不是同一届的,请你通过编程计算出来

Input t组输入(1<=t<=1000),每组输入一个数n(1<n<32768)

Output 输出一个数,表示和LSZ不是同一届的人数

Sample Input 1

2
25608
24027
Sample Output 1
7680
16016

思路如下:

这题类似于素数筛选的算法,比如n%2==0,表示2和n不互素,那么2的倍数和n都有2这个公因数,也不会互素,然后把2的倍数全都标记,这个算法类似于素数筛选

题解如下:

#include<iostream>
#include<string.h> using namespace std;
int vis[40000];
int n; void Solve()
{
memset(vis,0,sizeof(vis));
for(int i = 2;i <= n;i ++)
{
if(! vis[i])
{
if(n % i == 0)
{
for(int j = i;j <= n;j += i)
{
vis[j] = 1;
}
}
}
} } int main()
{
int t;
scanf("%d",&t);
while(t--)
{
cin>>n;
int sum = 0;
Solve();
for(int i = 1;i <= n;i ++)
{
if(! vis[i])
{
sum++;
}
} printf("%d\n",sum);
}
return 0;
}

LSZ的签到题(大数相加问题)

Description 既然是签到题,那么就没必要出的太难了。给你两个正整数a,b,请你输出a+b的值

Input t组输入,每组输入两个数a,b(0<=a,b<=10^100)

Output 输出a+b的值

Sample Input 1

2
10000 100
0123 03
Sample Output 1
10100
126

题解如下:

#include<iostream>
#include<cstring> using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
char a[100000],b[100000]; //定义存储字符串
scanf("%s %s",a,b);
int A[100000] = {0},B[100000] = {0}; //转存倒叙转存到,A、B数组中
int LEN_a = (int)strlen(a);
int LEN_b = (int)strlen(b);
for(int i = LEN_a - 1;i >= 0;i --)
{
A[LEN_a - i - 1] = a[i] - '0';
}
for(int i = LEN_b - 1;i >= 0;i --)
{
B[LEN_b - i - 1] = b[i] - '0';
}
int max_LEN;
if(LEN_a > LEN_b)
max_LEN = LEN_a;
else
max_LEN = LEN_b;
for(int j = 0;j < max_LEN;j ++)
{
A[j] += B[j];
}
for(int k = 0;k < max_LEN+10;k ++) //对A数组的每一位进行进位处理
{
if(A[k] > 9)
{
A[k+1] += A[k] / 10;
A[k] %= 10;
}
}
int digit = max_LEN + 10;
while(digit > 0 && A[digit] == 0) //去掉数组最后边的0
{
digit--;
}
for(int l = digit;l >= 0;l --)
printf("%d",A[l]);
printf("\n"); } return 0;
}

Description(数据范围不大 dfs爆搜)

YZJ学长有一个问题想请教大家

给出两个整数m,n(0<=n<=m<10^20),YZJ学长想知道m除第一位外的每一位经过‘+’或‘-’运算后的结果等于n的方案数量

例如 m=1111,n=0,方案:1+1-1-1=0,1-1-1+1=0,1-1+1-1=0 方案数量:3

例如 m=21,n=1,方案:2-1=1 方案数量:1

Input

多组数据输入

第一行输入m和n用空格隔开

Output

输出所有的方案个数

Sample Input 1

1111 0

Sample Output 1

3

Sample Input 2

21 1

Sample Output 2

1

Sample Input 3

11111111111111111111 2
Sample Output 1
3
Sample Output 2
3
Sample Output 3
92378

题解如下:

#include<iostream>
#include<string.h>
using namespace std;
long long int n;
int br[1000000];
long long int ans;
long long int LEN_ar; int pos = 0;
void dfs(int k,int zhi)
{
if(k == LEN_ar-1)
{
if(zhi == n-br[0])
ans++;
return;
}
dfs(k + 1,zhi + br[k+1]);
//dfs(k + 1,zhi + br[pos+1]); 注意这里的 br[pos+1] 一定不要这样写,因为,pos并不是 dfs的一个参数,所以在每一次dfs自己调用自己的时候pos的值都是0,我就是愣了半天硬是没看出来 每一次(pos+1)值均是不变的
dfs(k + 1,zhi - br[k+1]);
//dfs(k + 1,zhi - br[pos+1]); } int main()
{
char ar[100000];
while(cin>>ar>>n)
{
pos = 0;
ans = 0;
LEN_ar = (int)strlen(ar);
for(int i = 0;i < LEN_ar;i ++)
br[i] = ar[i] - '0';
dfs(0,0);
cout<<ans<<endl;
}
return 0;
}

2019NYIST计科第七次周赛总结的更多相关文章

  1. 2019NYIST计科第四次周赛

    YZJ的牛肉干 Description 今年的ACM暑期集训队一共有18人,分为6支队伍.其中有一个叫做 YZJ的大佬,在共同的集训生活中,大家建立了深厚的友谊, YZJ准备做点什么来纪念这段激情燃烧 ...

  2. 基于SCRUM方法实践的西油计科党建设计与实现

    基于SCRUM方法实践的西油计科党建设计与实现 序言 所属课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesig ...

  3. 北工大耿丹学院16级计科院3班C语言课程助教学期总结

    很荣幸得到邹老师,周老师,以及北工大耿丹学院各位老师的认可,担任计科院3班C语言课程助教,班主任为李光杰老师,很感谢李老师一学期的帮助,使得我更好的担任助教一职.我班学生31名,很愉快的与同学们度过一 ...

  4. 用HTML+CSS编写一个计科院网站首页的静态网页

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 计科1111-1114班第一次实验作业(NPC问题——回溯算法、聚类分析)

    实验课安排 地点: 科技楼423 时间:  计科3-4班---15周周一上午.周二下午 计科1-2班---15周周一下午.周二晚上(晚上时间从18:30-21:10) 请各班学委在实验课前飞信通知大家 ...

  6. 基于SCRUM方法实践的西油计科党建设计与实现-个人实践流程清单

    基于SCRUM方法实践的西油计科党建设计与实现 个人实践流程清单 一.Alpha版本冲刺个人在SCRUM团队任务清单: 时间 我这个三天做了什么 实际解决燃尽图项目数量 我遇到了什么问题 我下一个三天 ...

  7. Java课程设计-算术运算测试(D级) 齐鲁工业大学 计科20-1 王瀚垠 202003010033

    Java课程设计-算术运算测试(D级) 齐鲁工业大学 计科20-1 王瀚垠 202003010033 目录 1.项目简介 2.项目采用技术 3.功能需求分析 4.项目亮点 5.项目功能架构图和UML类 ...

  8. 1415-2 计科&计高 软件工程博客&Github地址汇总-修正版

    序号 标识 博客 代码 1 1121袁颖 joanyy joanyy 2 1122崔琪 chitty ChittyCui 3 1123吕志浩 lucy123 715lvzhihao 4 1124张静 ...

  9. 2017<java技术>预备作业计科冀浩然

    1.阅读邹欣老师的博客,谈谈你期望的师生关系是什么样的? 我期望的师生关系是相互融洽的,老师能够在上课的时候尽量多的教我们专业知识,可以尽量多和我们进行互动,课下能和我们如同朋友一般就可以了. 2.你 ...

随机推荐

  1. 钉钉小程序不用canvas在后端绘图前端用image标签获取图片的实践

    公司的需求要用电子员工卡代替用了N久的工作证,在各种场合刷二维码来代替刷卡.在钉钉小程序里实现.感觉这回又要躺坑里了. 钉钉小程序第一次做.我这个自封的GDI+大神才不要想用钉钉jsapi的方式用ca ...

  2. Asp.NET MvC EF实现分页

    打开Visual Studio 2017 选择 项目----->管理nuget包  其他版本也有 输入paged 下载安装 pagedList和pagedList.mvc 在model文件新建一 ...

  3. django 从零开始 制作一个图站 1环境的配置以及测试本地服务器

    先使用用virtualenv建立一个虚拟环境 使用pycharm 建立一个django项目 选择虚拟环境和建立一个应用app 其中 tuzhan是项目根目录 user是我们的项目app 中间一些项目文 ...

  4. c++第二周阶段小测2

    函数参数已完成(全部是正确答案)     1 [单选题] 以下关于函数参数的说法,不正确的是   A. 函数调用时,先将实参的值按照位置传递给对应的形参. B. 实参与形参的个数及顺序不必一一对应. ...

  5. ML-Agents(二)创建一个学习环境

    ML-Agents(二)创建一个学习环境 一.前言 上一节我们讲了如何配置ML-Agents环境,这一节我们创建一个示例,主要利用Reinforcement Learning(强化学习). 如上图,本 ...

  6. 10.xadmin后台使用管理

    目录 xadmin后台管理 xadmin后台管理 安装:luffy虚拟环境下 >: pip install https://codeload.github.com/sshwsfc/xadmin/ ...

  7. php 数据库 操作

    header.php <?php error_reporting(0);//加上error_reporting(0);就不会弹出警告了 // header("Content-type: ...

  8. 移动端Rem适配(基于vue-cli3 ,ui框架用的是vant-ui)

    介绍postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 remlib-flexible 用于设置 rem 基准值 1.安装lib-flexible(用于设置 rem 基准值 ...

  9. 【TIJ4】照例,每个分类的第一篇文章随便说两句

    [其实没啥好说的,完].... 嘛,其实本来也就是放练习的地方. 如果说世界上的课本按练习难度分成两类,一类是像Weiss那种习题比内容难的,还有就是TIJ这种讲得详尽但是习题相对简单的了吧. 不过不 ...

  10. 036.集群网络-K8S网络模型及Linux基础网络

    一 Kubernetes网络模型概述 1.1 Kubernetes网络模型 Kubernetes网络模型设计的一个基础原则是:每个Pod都拥有一个独立的IP地址,并假定所有Pod都在一个可以直接连通的 ...