问题 C: 错误票据
时间限制: 1 Sec 内存限制: 512 MB
提交: 162 解决: 95
[提交][状态][讨论版]
题目描述
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
输入
要求程序首先输入一个整数N(N<100)表示后面数据行数。
接着读入N行数据。
每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000),请注意行内和行末可能有多余的空格,你的程序需要能处理这些空格。
每个整数代表一个ID号。
输出
要求程序输出1行,含两个整数m n,用空格分隔。
其中,m表示断号ID,n表示重号ID
样例输入
2
5 6 8 11 9
10 12 9
样例输出
7 9
提示
[提交][状态][讨论版]
中文 English
心得:重点是他的n的断开的条件。
#include<bits/stdc++.h>
using namespace std;
int a[1200];
int main(void)
{
int n,m,i=0,d,c,j=0;
char ch;
memset(a,0,sizeof(a));
scanf("%d",&n);
getchar();
while(j<n)
{
scanf("%c",&ch);
if(ch=='\n') j++;
else if(ch>='0'&&ch<='9')
{
a[i]=ch-'0';
i++;
}
}
sort(a,a+i);
for(j=i;j>=0;j--)
{
if(a[j]==a[j-1]) d=a[j];
else if(a[j]-a[j-1]==2) c=(a[j]+a[j-1])/2;
if(d!=0&&c!=0) break;
}
printf("%d %d\n",c,d);
return 0;
}
心得:对称图形,将它折叠,再找规律。
#include<bits/stdc++.h>
using namespace std;
char a[1200][1200];
int main(void)
{
int n,N,i1,j1,i,j;
memset(a,'.',sizeof(a));
scanf("%d",&N);
n=9+(N-1)*4;
int t=n/2+1;
for(i1=1;i1<=n;i1++)
{
for(j1=1;j1<=n;j1++)
{
if(i1>t) i=n+1-i1;else i=i1;
if(j1>t) j=n+1-j1;else j=j1;
if(i==j&&i!=1&&j!=1&&i%2&&j%2)
{
a[i1][j1]='$';
}
else if(i%2&&i+1<j)
{
a[i1][j1]='$';
}
else if(i%2==0&&i==j-1) a[i1][j1]='$';
else if(j%2&&j+1<i)
{
a[i1][j1]='$';
}
else if(j%2==0&&j==i-1) a[i1][j1]='$';
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
printf("%c",a[i][j]);
printf("\n");
}
return 0;
}
问题 F: wjw的排序问题
时间限制: 1 Sec 内存限制: 128 MB
提交: 316 解决: 89
[提交][状态][讨论版]
题目描述
菜鸡wjw觉得最近对排序算法的理解又上了一个档次,于是准备研究一下自己会的所有排序算法,经过测试,他写的所有代码里最快的只有一句话"std::sort(a,a+len)",于是他终于发现自己依旧是个菜鸡...
那么问题来了,如果不用"std::sort()",你能写出什么样的排序代码呢?
输入
一组数据,第一行一个n表示序列长度(1<=n<=3000000)
第二行包含n个数字,用空格隔开
输出
升序排序后的结果,用空格隔开,末尾没有空格
样例输入
5
1 3 2 4 5
样例输出
1 2 3 4 5
提示
这道题做过,是堆排序
#include<bits/stdc++.h>
using namespace std;
const int INF=3000300;
int a[INF],b[INF];
void f(int a[],int l,int m,int r)
{
int i=l,j=m+1;
int t=l;
while(i<=m&&j<=r)
{
if(a[i]<a[j])
b[t++]=a[i++];
else
b[t++]=a[j++];
}
while(i<=m)
b[t++]=a[i++];
while(j<=r)
b[t++]=a[j++];
for(i=l;i<=r;i++)
a[i]=b[i];
}
void Merge(int a[],int l,int r)
{
if(l<r)
{
int m=(l+r)/2;
Merge(a,l,m);
Merge(a,m+1,r);
f(a,l,m,r);
}
}
int main()
{
int n,i;
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d",&a[i]);
Merge(a,0,n-1);
for(i=0;i<n-1;i++) printf("%d ",a[i]);
printf("%d\n",a[i]);
return 0;
}
问题 G: 统计数字
时间限制: 1 Sec 内存限制: 128 MB
提交: 210 解决: 97
[提交][状态][讨论版]
题目描述
某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。
输入
输入文件count.in包含n+1行:
第1行是整数n,表示自然数的个数。
第2~n+1行每行一个自然数。
输出
输出文件count.out包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。
样例输入
8
2
4
2
4
5
100
2
100
样例输出
2 3
4 2
5 1
100 2
提示
40%的数据满足:1<=n<=1000
80%的数据满足:1<=n<=50000
100%的数据满足:1<=n<=200000,每个数均不超过1 500 000 000(1.5*109)
[提交][状态][讨论版]
用map,优先队列,set模拟一下
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
set <LL> s;
map <LL,LL> m;
priority_queue <LL,vector<LL>,greater<LL> > q;
int main(void)
{
LL n,t,i;
scanf("%lld",&n);
for(i=0;i<n;i++)
{
scanf("%lld",&t);
if(s.count(t)) m[t]++;
else
{
m[t]=1;
s.insert(t);
q.push(t);
}
}
while(!s.empty())
{
s.erase(q.top());
printf("%lld %lld\n",q.top(),m[q.top()]);
q.pop();
}
return 0;
}
1977: 黑暗意志
时间限制: 1 Sec 内存限制: 128 MB
提交: 97 解决: 48
[提交][状态][讨论版]
题目描述
在数千年前潘达利亚从卡利姆多分离之时,迷雾笼罩着这块新形成的大陆,使它不被外来者发现。迷雾同样遮蔽着这片大陆古老邪恶的要塞——雷神的雷电王座。在雷神统治时期,他的要塞就是雷电之王力量的保障。即使在他死后,强大而堕落的能量仍然在此萦绕不绝;而复活的雷电之王和赞达拉巨魔企图再次驾驭那股能量,重建昔日帝国。这就是魔兽世界5.2版本的大型团队副本"雷电王座"
雷电王座中有一个神奇的BOSS是所有玩家都会记得的,直到现在当你的人物血量比BOSS血量都高的时候,在战斗的时候都要注意自己是不是会一不留神死在这个BOSS面前,它就是"黑暗意志"
黑暗意志的整场战斗围绕着一种神秘、旋转的液体——心能;它们是在这侧厅室内魔古实验的核心。这些重要的液体有固定的量并能激活魔像。当最初储藏它们的容器被摧毁后,逃逸出的液体会不断流向越来越大的构造体;直至它们的量聚集到一定程度后,便会激活所有魔像中最大的一个——黑暗意志。
击杀这个BOSS需要团队玩家一个人面向一个小魔像,在保证不击杀小魔像的情况下存活并且对BOSS进行输出,并且在需要时击杀小魔像以减轻治疗压力,提高对BOSS的输出
但是在炼狱难度下,玩家不但要保证不击杀小魔像,更要保证任意一个小魔像本身的血量,有另一个小魔像的血量与它相同,那么这两个小魔像之间便会形成一条连线(每个小魔像只能连接一条线),同时小魔像上会出现一个debuff(减少小魔像50%的输出),显然这个debuff在炼狱难度下的副本战斗中至关重要。
所以在炼狱难度开荒的时候,队长会给两个DPS差不多的玩家组队,让这两个玩家保证自己的小魔像与另一个人的小魔像血量相同,但是在团灭五次之后,团长终于发现,不是治疗不够,而是有两个玩家的DPS与之前的DPS有了差别,所以总是不能保证他们这一组的小魔像血量相同,但是这个时候,每对玩家彼此都有了默契,重新分组显然是不明智的,那么团长准备自己去帮助那两个玩家,保证他们的小魔像血量相同,但是团长需要知道,他们两个的小魔像血量是多少,才可以去攻击那个血量较多的小魔像,来保证这两个小魔像血量相同,从而击杀BOSS。
所以现在告诉你所有小魔像的血量,你能告诉团长,那两个玩家所对应的小魔像血量是多少吗?
输入
第一行一个整数T,代表数据的组数(1<=T<=10),接下来T组数据,每组数据的第一行是一个整数n(2<=n<=1000000,保证n是偶数),第二行是n个整数ai(0 <= ai <= 1000000000)代表血量,每两个整数之间有一个空格,(输入保证有且只有两个小魔像无法连线)
输出
对于每组数据,输出两个整数,分别代表两个小魔像的血量,中间有一个空格,并且血量较大的先输出。
样例输入
2
6
2 2 1 1 3 4
4
1 1 3 4
样例输出
4 3
4 3
提示
来源
jnxxhzz
找不同
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a[1000100];
int main(void)
{
int n,i,r;
LL t;
scanf("%d",&r);
while(r--)
{
int fg=0,l=0,b[5];
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%lld",&a[i]);
sort(a,a+n);
for(i=0;i<n;i++)
{
if(a[i]==a[i+1]) i++;
else b[l++]=a[i];
}
if(b[0]>b[1]) printf("%d %d\n",b[0],b[1]);
else printf("%d %d\n",b[1],b[0]);
}
return 0;
}
1978: 调酒壶里的酸奶
时间限制: 1 Sec 内存限制: 128 MB
提交: 165 解决: 43
[提交][状态][讨论版]
题目描述
最近小w学了一手调酒的技巧,这么帅的操作,说不定能靠这个俘获女神的芳心,为了在女神面前露一手,他想在学校里建一个"pub",但是显然学校不可能让他真的建一个"pub",那么他退而求次,想建一个"Yogurt shop",不能用酒,那用酸奶也行啊!
今天女神终于来光顾小w的酸奶店了!兴奋的小w拿出自己准备已久每天都仔细擦干净的装备——调酒壶、果汁机、隔冰器和计量杯、砧板、小刀....准备露一手给女神看看
但是女神却没有那么多耐心,女神只是觉得,自己买一瓶大酸奶喝不完,小瓶酸奶不够喝,所以在小w的酸奶店,说不定她可以想买多少就买多少。
于是女神告诉了小w她想要多少体积的酸奶,而小w却依旧想秀一下自己的操作,于是他决定用仅有的两个调酒壶为女神倒出女神想要的酸奶....
小w的两个调酒壶体积是不同的(一开始都是空的),小w每次可以选择一个调酒壶倒入另一个调酒壶(若A倒入B,A倒完或B倒满则停止),或者选择一个调酒壶倒光,或者选择一个调酒壶去接满酸奶.....
满心失望的小w想找一朵花,一瓣一瓣的撕下来,问问花朵女神到底喜不喜欢他...虽然这个答案是显而易见的,但是他还是想找一朵花...然而找花未果,反正花瓣不是偶数就是奇数,那他索性就用自己的操作次数作为花瓣个数吧!(找不到花我还不能脑补一朵吗...)
但是小w已经没有心情去想答案了...那么你能告诉他,需要多少步操作才能倒出女神想要的酸奶吗?
输入
输入包含多组数据,每行三个正整数a,b,c分别表示两个调酒壶的容量以及女神想要的酸奶体积,a,b的范围都在[0,100],c<=max(a,b)
输出
一行包含一个整数表示完成要求的最少操作次数,若达不到则输出"impossible"(没有双引号)
样例输入
10 15 11
6 5 4
样例输出
impossible
4
提示
我不知道为什么酸奶可以倒进调酒壶,我也不知道为什么女神不喜欢小w,我只知道凭小w的想象力,游泳池都行更别说一朵花了!
来源
jnxxhzz
[提交][状态][讨论版]
这道题看了很久,是分6种情况,
1、A倒入B,(A可以倒光或者有剩余)
2、B倒入A,(B可以有剩余或者倒光)
3、A倒满
4、B倒满
5、A倒光
6、B倒光
结束条件是A中有c或B中有c
#include<bits/stdc++.h>
using namespace std;
int a,b,c,ans;
int v[120][120];
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
void dfs(int A,int B,int step)
{
if(A==c||B==c)
{
if(ans>step) ans=step;
return ;
}
v[A][B]=1;
if(A+B>=a)
{
if(!v[a][A+B-a]&&A+B-a<b)
{
dfs(a,A+B-a,step+1);
v[a][A+B-a]=0;
}
}
else
{
if(!v[A+B][0])
{
dfs(A+B,0,step+1);
v[A+B][0]=0;
}
}
if(A+B>=b)
{
if(!v[A+B-b][b]&&A+B-b<a)
{
dfs(A+B-b,b,step+1);
v[A+B-b][b]=0;
}
}
else
{
if(!v[0][A+B])
{
dfs(0,A+B,step+1);
v[0][A+B]=0;
}
}
if(A<a&&!v[A][b])
{
dfs(A,b,step+1);
v[A][b]=0;
}
if(B<b&&!v[a][B])
{
dfs(a,B,step+1);
v[a][B]=0;
}
if(A>0&&!v[A][0])
{
dfs(A,0,step+1);
v[A][0]=0;
}
if(B>0&&!v[0][B])
{
dfs(0,B,step+1);
v[0][B]=0;
}
}
int main(void)
{
while(~scanf("%d%d%d",&a,&b,&c))
{
if(a<b) swap(a,b);
if(c%gcd(a,b))
{
printf("impossible\n");
}
else
{
memset(v,0,sizeof(v));
ans=100*100;
dfs(0,0,0);
printf("%d\n",ans);
}
}
return 0;
}
参考文章:https://blog.youkuaiyun.com/zz1049694353/article/details/78420351
1958: 机器翻译
时间限制: 1 Sec 内存限制: 128 MB
提交: 179 解决: 89
[提交][状态][讨论版]
题目描述
小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义 来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有, 软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中 文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。 假设内存中有 M 个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入 内存前,如果当前内存中已存入的单词数不超过 M−1,软件会将新单词存入一个未使用的 内存单元;若内存中已存入 M 个单词,软件会清空早进入内存的那个单词,腾出单元来, 存放新单词。 假设一篇英语文章的长度为 N 个单词。给定这篇待译文章,翻译软件需要去外存查找多 少次词典?假设在翻译开始前,内存中没有任何单词。
输入
输入文件名为 translate.in,输入文件共 2 行。每行中两个数之间用一个空格隔开。 第一行为两个正整数 M 和 N,代表内存容量和文章的长度。 第二行为 N 个非负整数,按照文章的顺序,每个数(大小不超过 1000)代表一个英文 单词。文章中两个单词是同一个单词,当且仅当它们对应的非负整数相同。
输出
输出文件 translate.out 共 1 行,包含一个整数,为软件需要查词典的次数。
样例输入
3 7
1 2 1 5 4 4 1
样例输出
5
提示
【输入输出样例 1 说明】 整个查字典过程如下:每行表示一个单词的翻译,冒号前为本次翻译后的内存状况:
空:内存初始状态为空。
1. 1:查找单词 1 并调入内存。
2. 1 2:查找单词 2 并调入内存。
3. 1 2:在内存中找到单词 1。
4. 1 2 5:查找单词 5 并调入内存。
5. 2 5 4:查找单词 4 并调入内存替代单词 1。
6. 2 5 4:在内存中找到单词 4。
7. 5 4 1:查找单词 1 并调入内存替代单词 2。
共计查了 5 次词典。
来源
NOIP2010提高组
[提交][状态][讨论版]
用队列模拟一下。
#include<bits/stdc++.h>
using namespace std;
int a[1200];
int main(void)
{
int n,m,i,t,cnt=0,r=0;
scanf("%d%d",&m,&n);
memset(a,0,sizeof(a));
queue <int> q;
for(i=0;i<n;i++)
{
scanf("%d",&t);
if(a[t]==0)
{
if(r<m)
{
q.push(t);
a[t]=1;
r++;
cnt++;
}
else if(r==m)
{
q.push(t);
a[q.front()]=0;
a[t]=1;
q.pop();
cnt++;
}
}
}
printf("%d\n",cnt);
return 0;
}