2014湖南农业大学ACM校赛

湖南农业大学 2014年 ACM 校赛Problem

                                                               2014 /2/23  星期日  12:30-17:30

A.搜素      1794.查找指定的字符串     
B.链表      1795 争当幸运儿
C.Date     1796  时间日期                            JAVA
D.筛选法  1797 反素数
       
E.模拟      1798 照片冲印
F.动归
G.计算几何
H. 位运算   UTF-8 转Unicode



A .查找指定的字符串

Description

在二维字符阵列中寻找指定的字符串。

Input

前两行分别指示字符矩阵的宽w和高h(1<=w<=7 且 1<=h<=7)。接下来的h行每行w个字符便是字符矩阵的内容,再下面的1行为要寻找的字符串的数目n(n<4),其后的n行便是要寻找的字符串,每个字符串不会超过7个字符。

Output

n行,每行保存1个字符串的位置。位置的格式形如(1,2)->(2,6),意为该字符串首字母在字符矩阵中的位置是第1列2行,尾字母在字符矩阵中的位置是第2列6行。

Sample Input

5

5

ABCDO

FHHIL

KILLL

QKSOE

VWKYH

3

KKK

KILL

HELLO

Sample Output

(1,3)->(3,5)  

(1,3)->(4,3)

(5,5)->(5,1)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define  M 9

char graph[M][M];
char temp[M];
int w,h;
struct point{
  int x,y;
  bool ok()
  {
      return (x>=0&&x<h&&y>=0&&y<w);
  }
};
point  s,e,now;
int dir[8][2]={{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{-1,1},{1,1},{1,-1}};
    /*  上 右 下 左 左斜上 右斜上 右斜下 左斜下*/
int  mysearch(int i,int j)
{
    int  len=strlen(temp);
    if(len==1){e.x=s.x; e.y=s.y;return 1;}
    for(int i=0;i<8;i++)
    {
        now.x=s.x+dir[i][0];
        now.y=s.y+dir[i][1];
        int k=1;
        while(now.ok()&&graph[now.x][now.y]==temp[k++])
        {
            if(k==len){e.x=now.x;e.y=now.y;return 1;}
            now.x+=dir[i][0];
            now.y+=dir[i][1];
        }
    }
    return 0;
}
void  solve()
{
    for(int i=0;i<w;i++)
    for(int j=0;j<h;j++)
    if(graph[i][j]==temp[0])
    {
       s.x=i;s.y=j;
       if(mysearch(i,j))
       {
           printf("(%d,%d)->(%d,%d)\n",s.y+1,s.x+1,e.y+1,e.x+1);
           return ;
       }
    }
}
int main()
{
    int n;
    while(~scanf("%d%d",&w,&h))
    {
        for(int i=0;i<h;i++)
        {
            scanf("%s",graph[i]);
        }
        scanf("%d",&n);
        while(n--)
        {
            scanf("%s",temp);
            solve();
        }

    }
    return 0;
}

B 1795 争当幸运儿

Description

n个人围成一圈,并依次编号1~n。从编号为1的人开始,按顺时针方向每隔2人选出1个,剩下的人重新围成一圈,如此循环直到剩下两人,这剩下的两人就是幸运儿。如果你想成为最后两个幸运儿,请问开始时应该站在什么位置?(设3<=n<=50)

 

Input

开始时的人数n

 

Output

第1行是选出顺序,第2行是两名幸运儿开始的位置(按升序排列),位置编号之间用一个空格分开。

 

Sample Input

13

Sample Output

3 6 9 12 2 7 114 10 5 1     

8 13

HINT


注意:输出的第一行末尾有一个空格。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;


int n;
struct node{
    int data;
    node* next;
}*pre,*p,*head;
void creat()
{
   p=new node();
   p->data=1;
   head=p;
   for(int i=2;i<=n;i++)
   {
       pre=p;
       p=new node();
       p->data=i;
       pre->next=p;
   }
    p->next=head;
}
void myshow()
{
    for(int i=1;i<=n-2;i++)
    {
        p=p->next->next;
        pre=p;
        p=p->next;
        pre->next=p->next;
        printf("%d ",p->data);
        delete p;
        p=pre;
    }
    printf("\n");
    if(p->data < p->next->data)
        printf("%d %d\n",p->data,p->next->data);
    else
        printf("%d %d\n",p->next->data,p->data);
    delete p->next;
    delete p;
}

int main()
{

    while(~scanf("%d",&n))
    {
        creat();
        myshow();
    }
    return 0;
}


C 时间日期

Description

计算机系统对当前系统时间的表示采用了一种比较奇怪的方式,它记录了相对于1970年元月1日零时零分零秒至当前的毫秒数。如果时间在1970年之前,那么此值为负。1970年元月1日00:00:00称为UNIX元年(UNIX epoch),因为UNIX操作系统是在概念正式发布。现在给定一个整数,表示距UNIX元年的毫秒数,请编程计算出它所表示的年月日时分秒、毫秒(此处的毫秒为一秒内的剩余的毫秒数)、星期几。

Input

若干行,每行一个整数t(-2208988800000≤t≤4102444799999),表示毫秒数

 

Output

按照样例的格式输出,每行输出一个结果。年份按4位输出,月日时分秒按2位输出,秒后为一个小数点".",接着输出毫秒按3位输出,最后输出星期几。星期天用0表示,星期一用1表示,... ,星期六用6表示。注意,每行输出的末尾没有空格。

 

Sample Input

0
1392863010349

Sample Output

1970 01 01 00:00:00.000 4
2014 02 20 02:23:30.349 4

//package acm_code;

import java.util.*;
import java.text.*;

public class GetDateTime {



	/**
	 *  input:   681601001000
	 *  标准输出:1991 08 07 22:36:41.000 3
	 *  我的输出:1991 08 07 21:36:41.000 3
	 */
	/**
	 * @param 输入一个long型的系统毫秒值
	 * @throws ParseException
	 */
	public static void main(String[] args) throws ParseException{
		Scanner in=new Scanner(System.in);
		//设置默认时区为格林威治时间 0时
		TimeZone.setDefault(TimeZone.getTimeZone("GMT+0:00"));

		System.out.println(TimeZone.getDefault());

	    DateFormat df=new SimpleDateFormat("yyyy MM dd HH:mm:ss.SSS ");
	    Calendar cal=Calendar.getInstance();
	    Date  date=new Date(0L);
	    long n;
	    while(in.hasNextLong())
	    {
		   n=in.nextLong()-28800000;
		   date.setTime(n);
		   String prefix =df.format(date);
		   //下面求星期几
		   cal.setTimeInMillis(n);
		   int week=cal.get(Calendar.DAY_OF_WEEK)-1;
		   System.out.println(prefix+week);
	    }
	    in.close();
	}
}

D 反素数

Description

n为反素数是指n本身是素数,将反向构成的数也是素数,但n不是回文数。例如13是反素数,但是131就不是反素数,因为它是回文数。

Input

第一行有一个整数k(1<=k<=100),表示测试用例的个数,其后的k行,没行有两个整数m,n(1<=m<N<=1000000)。< p>

Output

请输出每个[m,n]区间内的所有反素数。如果没有,则输出"not found"。请注意输出的格式:两个测试用例之间的有且仅有一个空行。每个测试用例的输出中,每行输出10个反素数,同行的两个反素数之间用1个空格分隔,每行的行尾没有空格。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#include <time.h>
#define M 1000000
bool prime[M+5];
int ans[M/10],len=0;
void getPrime()
{
    int i,j;
    //memset(prime,0,sizeof(prime));
    for(i=2;i<=sqrt(M);i++)
     if(!prime[i])
     { for(j=i*i;j<=M;j+=i)
         prime[j]=1;
     }
}
int convert(int x)
{
    int l=0,flag=0,temp=0;
    int a[6];
    while(x)
    {
        a[l++]=x%10;
        x/=10;
    }
    for(int i=0;i<l/2;i++)
     if(a[i]!=a[l-1-i])
      {flag=1; break;}
    if(flag==0)return 0;//是回文数
    for(int i=0;i<l;i++)
     temp=temp*10+a[i];
   //  if(l==2)printf("temp==%d\n",temp);
    if(!prime[temp])return 1;//是素数
    return 0;
}
void solve()
{
    for(int i=12;i<M;i++)
    if(!prime[i])
    {
        if(convert(i))
            ans[len++]=i;
    }
   // printf("78385总个数为:%d\n",len);
}
void show(int a,int b)
{
    int first=1,cnt=0,i=0;
    while(a>ans[i])i++;
    while(ans[i]<=b&&i<len)
    {
        if(first)
        { printf("%d",ans[i]);cnt++;first=0;}
        else
        {
           if(cnt%10==0)printf("\n");
           else printf(" ");
           printf("%d",ans[i]);
           cnt++;
        }
        i++;
    }
    if(first){printf("not found\n");return;}
    //结束当前行
    printf("\n");
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,a,b;
    getPrime();
    solve();
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d%d",&a,&b);
        show(a,b);
        if(n!=0)printf("\n");
    }
    return 0;
}
E 照片冲印

Description

某次班级集体活动中,大家玩的非常开心,并且由一位擅长摄影的同学拍摄许许多多的照片,活动结束后,大家需要冲印本次活动的照片。为了方便冲印,将所有的照片从1开始顺序编号。然后每位同学提出自己需要冲印的照片。通过如下三种方式指定:(1)单个数字m(1<=m<=10000),表示冲印此编号照片1张。(2)如果需要的照片编号连续,可以使用“m-n”的表示(1<=m<N<=10000)。(3)如果某个同学需要的编号为N的照片冲印X张,这可用N*X表示。照片编号之间用逗号分隔。 p 现在需要按两种方式处理此数据,一是为照相馆准备的数据,照相馆在冲印照片时,需要知道每张照片的冲印数量;二是为负责收取冲印费的同学准备的数据。冲印照片是收费的,由每位冲印照片的同学付费,为了方便收费,需要知道每个同学冲印照片的张数。<>

Input

第一行包含一个整数k1<=k<=1000),表示测试用例的个数。其后共有n个测试用例。每个测试用例的第一行为需要照片的人数n1<=n<=100)。其后的n行中,每行包含用逗号分隔的表示所需照片编号,第1行表示1号同学需要的照片,第2行表示2号同学需要的照片,依此类推。最大照片编号小于等于10000

Output

每个测试用例输出2行。第一行输出需要冲印的每张照片的数量,如果照片数量为1则输出该编号,如果大于1则输出编号*张数,按照片编号从小到大排列,不需要冲洗的照片不要列出来。第二行顺序地输出每个同学冲印照片的张数。i注意,同行两项输出之间用1个空格分隔,但是每行输出的末尾没有空格。测试用例的输出之后有1个空行。

Sample Input

2
1
1-10
3
2,5-12,15*3,14,6-8
1,3*2,7,3*4,5,2,4,3
10*2,15,8,6-11

Sample Output

1 2 3 4 5 6 7 8 9 10
10
 
1 2*2 3*7 4 5*2 6*3 7*4 8*4 9*2 10*4 11*2 12 14 15*4
16 12 10
//package acm_code;

import java.util.Scanner;

public class Main {
	public static int n;
	public static void main(String[] args) {
		Scanner in=new  Scanner(System.in);
	    int cases;
	    int[] photo=new int[10002];
	    int[] people=new int[1002];
	    String str;
	    int maxn=0;
	    cases=in.nextInt();
	    while(cases-->0)
	    {
	    	for(int i=1;i<10002;i++)
	    		photo[i]=0;
	    	for(int i=1;i<1002;i++)
	    		people[i]=0;
	    	
	    	n=in.nextInt();
	    	in.nextLine();
	    	for(int i=1;i<=n;i++)
	    	{
	    		str=in.nextLine();
	    		String []token=str.split(",");
	    		
	    		for(int j=0;j<token.length;j++)
	    		{
	    			if(token[j].contains("-"))
	    			{
	    				String [] b=token[j].split("-");
	    				int a=Integer.parseInt(b[0]);
	    				int c=Integer.parseInt(b[1]);
	    				for(int k=a;k<=c;k++)
	    					photo[k]++;
	    				people[i]+=c-a+1;
	    				
	    				if(maxn<c)maxn=c;
	    			}else if(token[j].contains("*")){
						
	    				String [] b=token[j].split("[*]");
	    				int a=Integer.parseInt(b[0]);
	    				int c=Integer.parseInt(b[1]);
	    				photo[a]+=c;
	    				people[i]+=c;
	    				
	    				if(maxn<a)maxn=a;
					}else {
						int a=Integer.parseInt(token[j]);
						people[i]++;
						photo[a]++;
						
						if(maxn<a)maxn=a;
					}
	    			
	    		}
	    	}
	    	boolean first=true;
	    	for(int i=1;i<=maxn;i++)
	    	if(photo[i]>0)
	    	{
	    		if(first){
	    			if(photo[i]==1) System.out.print(i);
	    			else System.out.print(i+"*"+photo[i]);
	    			first=false;
	    		}else {
					System.out.print(" ");
					if(photo[i]==1) System.out.print(i);
	    			else System.out.print(i+"*"+photo[i]);
				}
	    	}
	    	System.out.print("\n");
	    	for(int i=1;i<=n;i++)
	    	{
	    		if(i!=1)System.out.print(" ");
	    		System.out.print(people[i]);
	    	}
	    	System.out.print("\n\n");
	    	
	    }
		in.close();
	}

}


H  UTF-8 转Unicode

#include <stdio.h>

int main()
{
    int n,temp,ans;//数据最大为32位
    int k;
    scanf("%d",&k);
    while(k--)
    {
        scanf("%x",&n);
        if(n<0x10000)printf("%04X\n",n);
        else{
            n=n-0x10000;
            temp=n&0x3FF;//取低10位
            ans=((n-temp)<<6)|0xD800DC00|temp;//分别填充
            printf("%08X\n",ans);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值