T1
问题描述
试题编号: | 201403-1 |
试题名称: | 相反数 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 有 N 个非零且各不相同的整数。请你编一个程序求出它们中有多少对相反数(a 和 -a 为一对相反数)。 输入格式 第一行包含一个正整数 N。(1 ≤ N ≤ 500)。 输出格式 只输出一个整数,即这 N 个数中包含多少对相反数。 样例输入 5 样例输出 2 |
思路:用标记数组Arr[r]记录出现次数,初始的时候Arr[r]=0;遍历整数,记当前遍历到的值r>0时,此时观察Arr[r]的值,若Arr[r]<0,表示之前有-Arr[r]个未被匹配的-r,可以和r匹配,而Arr[r]+1,表示-r匹配一个,答案累计加1,r<0时同理。
#include<iostream>
using namespace std;
int Arr[1010];
int main(){
int i,n,r,ans=0;
cin>>n;
for(i=1;i<=n;++i){
cin>>r;
if(r>=0){
if(Arr[r])++ans;
++Arr[r];
}
else{
if(Arr[-r])++ans;
--Arr[-r];
}
}
cout<<ans;
return 0;
}
T2
问题描述
试题编号: | 201403-2 |
试题名称: | 窗口 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。 输入格式 输入的第一行有两个正整数,即 N 和 M。(1 ≤ N ≤ 10,1 ≤ M ≤ 10) 输出格式 输出包括 M 行,每一行表示一次鼠标点击的结果。如果该次鼠标点击选择了一个窗口,则输出这个窗口的编号(窗口按照输入中的顺序从 1 编号到 N);如果没有,则输出"IGNORED"(不含双引号)。 样例输入 3 4 样例输出 2 样例说明 第一次点击的位置同时属于第 1 和第 2 个窗口,但是由于第 2 个窗口在上面,它被选择并且被置于顶层。 |
思路:直接模拟,需要的注意的是窗口的顺序以及点击后需要改变部分窗口的位置。
#include<iostream>
using namespace std;
const int N=15,M=15;
struct Window{
int Lx,Ly,Rx,Ry,index;
bool have(int x,int y){
return Lx<=x&&Rx>=x&&Ly<=y&&Ry>=y;
}
};
Window windows[N];
//越靠后越顶层
int main(){
int n,m,i,j,x,y;
Window temp;
cin>>n>>m;
for(i=1;i<=n;++i){
cin>>windows[i].Lx>>windows[i].Ly>>windows[i].Rx>>windows[i].Ry;
windows[i].index=i;
}
for(i=1;i<=m;++i){
cin>>x>>y;
for(j=n;j>0;--j){
if(windows[j].have(x,y)){//顶层窗口
break;
}
}
if(j==0)cout<<"IGNORED"<<endl;
else{
cout<<windows[j].index<<endl;
temp=windows[j];
for(;j<n;++j){
windows[j]=windows[j+1];
}
windows[n]=temp;
}
}
return 0;
}
T3
问题描述
试题编号: | 201403-3 |
试题名称: | 命令行选项 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 请你写一个命令行分析程序,用以分析给定的命令行里包含哪些选项。每个命令行由若干个字符串组成,它们之间恰好由一个空格分隔。这些字符串中的第一个为该命令行工具的名字,由小写字母组成,你的程序不用对它进行处理。在工具名字之后可能会包含若干选项,然后可能会包含一 些不是选项的参数。 输入格式 输入的第一行是一个格式字符串,它至少包含一个字符,且长度不超过 52。格式字符串只包含小写字母和冒号,保证每个小写字母至多出现一次,不会有两个相邻的冒号,也不会以冒号开头。 输出格式 输出有 N 行。其中第 i 行以"Case i:" 开始,然后应当有恰好一个空格,然后应当按照字母升序输出该命令行中用到的所有选项的名称,对于带参数的选项,在输出它的名称之后还要输出它的参数。如果一个选项在命令行中出现了多次,只输出一次。如果一个带参数的选项在命令行中出 现了多次,只输出最后一次出现时所带的参数。 样例输入 albw:x 样例输出 Case 1: -a -l |
思路:好像从这次认证开始,第三题就以题目量来恶心人了>-<,不难但是编码起来比较麻烦,思路就是直接模拟。
#include<iostream>
#include<map>
#include<sstream>
#include<string>
using namespace std;
map<string,string> Command;
int Argument[30];//0:压根没有这个选项 1:不带参数 2:带参数
bool leaglly(string str){//判断是否是合法的字符串
int n=str.length(),i;
if(!n)return false;//空字符串不是合法参数
for(i=0;i<n;++i){
if((str[i]<'a'||str[i]>'z')&&str[i]!='-'&&(str[i]<'0'||str[i]>'9'))return false;
}
return true;
}
int main(){
string format,str,part;
map<string,string>::iterator iter;
cin>>format;
int n=format.length(),i;
for(i=0;i<n;++i){
if(format[i]==':'){
Argument[format[i-1]-'a']=2;
}
else Argument[format[i]-'a']=1;
}
cin>>n;
getline(cin,str);
for(i=1;i<=n;++i){
getline(cin,str);
stringstream ss(str);
ss>>part;//先把开头的命令读掉
Command.clear();
while(ss>>part){
if(part.size()==2&&part[0]=='-'&&Argument[part[1]-'a']==1){
Command[part]="";
}
else if(part.size()==2&&part[0]=='-'&&Argument[part[1]-'a']==2&&ss>>str){
Command[part]=str;
}else break;
}
cout<<"Case "<<i<<": ";
for(iter=Command.begin();iter!=Command.end();++iter){
cout<<" "<<iter->first<<" "<<iter->second;
}
cout<<endl;
}
}
T4
问题描述
试题编号: | 201403-4 |
试题名称: | 无线网络 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要距离不超过 r 就能互相建立网络连接。 输入格式 第一行包含四个正整数 n,m,k,r。(2 ≤ n ≤ 100,1 ≤ k ≤ m ≤ 100, 1 ≤ r ≤ 108)。 输出格式 输出只有一个数,即在指定的位置中增设 k 个路由器后,从第 1 个路 由器到第 2 个路由器最少经过的中转路由器的个数。 样例输入 5 3 1 3 样例输出 2 |
思路:其实本题容易被误导,本题的表述容易让我们先入为主,先选定加几个加哪些位置的路由器,再来尝试调小,这样考虑问题会变得很复杂,实际上可以简化为一个简单的图遍历问题。我们把所有的路由器(包括可增设的)全部构建成图,然后遍历整个图,找到所有的1->2的路径,剔除掉那些路径上增设路由器个数超过k个的非法路径就可以得到答案。至于目标是不是还要保证所有的路由器连通,本题没说,我们也不需要考虑。
这样看题目就变得十分简单了,找最短路径,可以DFS+剪枝也可以BFS。
DFS + 剪枝:(可能超时)
#include<iostream>
#include<queue>
using namespace std;
const int N=110;
int n,m,k,ans=1000;
long long r;
bool visited[N];
struct Point{
long long x,y;
long long distance(long long px,long long py){
return (x-px)*(x-px)+(y-py)*(y-py);
}
}point[N*2];
void DFS(long long x,long long y,int count,int len){
if(count>k || len>ans)return;
if(x==point[2].x&&y==point[2].y){
ans=min(ans,len-1);
}
for(int i=2;i<=n+m;++i){
if(!visited[i]&&point[i].distance(x,y)<=r){//没有访问过并且可以达到
visited[i]=true;
if(i<=n){//旧路由
DFS(point[i].x,point[i].y,count,len+1);
}
else{//新路由
DFS(point[i].x,point[i].y,count+1,len+1);
}
visited[i]=false;
}
}
}
int main(){
cin>>n>>m>>k>>r;
r*=r;
int i;
long long x,y;
for(i=1;i<=n+m;++i)cin>>point[i].x>>point[i].y;
visited[1]=true;
DFS(point[1].x,point[1].y,0,0);
cout<<ans;
return 0;
}
BFS:
#include<iostream>
#include<queue>
using namespace std;
const int N=110;
int n,m,k,ans=1000;
long long r;
bool visited[N*2];
struct Point{
long long x,y;
}point[N*2];
struct Node{
long long x,y;
int count,len;
};
queue<Node> que;
long long distance(long long x,long long y,long long px,long long py){
return (x-px)*(x-px)+(y-py)*(y-py);
}
int BFS(Point p){
que.push(Node{p.x,p.y,0,0});
Node temp;
long long x,y;
int count,len,i;
while(!que.empty()){
temp=que.front();
que.pop();
x=temp.x,y=temp.y;
count=temp.count;
len=temp.len;
for(i=2;i<=n+m;++i){
if(!visited[i]&&distance(x,y,point[i].x,point[i].y)<=r){//没有访问过并且可以达到
if(i==2)return len;
if(i>n&&count==k)continue;
visited[i]=true;
if(i>n){//使用了新的路由
que.push(Node{point[i].x,point[i].y,count+1,len+1});
}else{
que.push(Node{point[i].x,point[i].y,count,len+1});
}
}
}
}
return 0;
}
int main(){
cin>>n>>m>>k>>r;
r*=r;
int i;
long long x,y;
for(i=1;i<=n+m;++i)cin>>point[i].x>>point[i].y;
visited[1]=true;
cout<<BFS(point[1]);
return 0;
}
T5
问题描述
试题编号: | 201403-5 |
试题名称: | 任务调度 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 有若干个任务需要在一台机器上运行。它们之间没有依赖关系,因此 可以被按照任意顺序执行。 输入格式 输入的第一行只有一个正整数 n(1 ≤ n ≤ 40), 是总共需要执行的任 务个数。 输出格式 输出只有一个整数,即完成给定的所有任务所需的最少时间。 样例输入 3 样例输出 7 样例说明 有很多种调度方案可以在 7 个时间单位里完成给定的三个任务,以下是其中的一种方案: |
思路:目前并没有发现什么好的思路>-<
DFS搜索:
#include<iostream>
using namespace std;
const int N=45;
int A[N],B[N],C[N],D[N],n,ans=0x7fffffff;
bool used[N];
void DFS(int now,int cpu1,int cpu2,int gpu){
if(now==n+1){
ans=min(ans,max(cpu1,cpu2));
}
for(int i=1;i<=n;++i){
if(!used[i]){
used[i]=true;
DFS(now+1,cpu1+A[i],cpu2,gpu);
DFS(now+1,cpu1,cpu2+A[i],gpu);
DFS(now+1,cpu1+B[i],cpu2+B[i],gpu);
DFS(now+1,cpu1+C[i],cpu2,gpu+C[i]);
DFS(now+1,cpu1,cpu2+C[i],gpu+C[i]);
DFS(now+1,cpu1+D[i],cpu2+D[i],gpu+D[i]);
used[i]=false;
}
}
}
int main(){
int i;
cin>>n;
for(i=1;i<=n;++i)cin>>A[i]>>B[i]>>C[i]>>D[i];
DFS(1,0,0,0);
cout<<ans;
return 0;
}