Contest2288

                                        Problem A: gift

                                                                  Time Limit: 1000 ms   Memory Limit: 128 MB

Input

输入的第一行为一个整数t。 接下来t行,每行包含九个自然数a,b,c,d,e,f,g,h,i

Output

输出t行,每行一个整数,表示2^a+2^b+2^c+2^d+2^e+2^f+2^g+2^h+i。

Sample Input

1
21 30 0 0 0 0 0 0 2147483647

Sample Output

3223322629

HINT

40%   t<=1000

100%  t<=100000 a,b,c,d,e,f,g,h<=60 i<=9223372036854775808


看到数据范围后,觉得这根本不是礼物好吗?

刚开始觉得要用高精度,后来发现用unsigned long long再加上极限数据的特判就行了。

AC code:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
unsigned long long a[10],ans,mi[65],inf=9223372036854775808;
int t,s;
int x[100],y[100];
unsigned long long mix(unsigned long long n){//快速幂
    if(mi[n]!=0)return mi[n];
    if(n%2==0)return mi[n]=mix(n/2)*mix(n/2);
    else return mi[n]=mix(n/2)*mix(n/2+1);
}
int main(){
    scanf("%d",&t);
    mi[0]=1;
    mi[1]=2;
    while(t--){
        ans=0;
        for(int i=1;i<=9;i++){
        	scanf("%llu",&a[i]);
        	if(i!=9)s+=a[i];
		};
        if(s==60*8&&a[9]==inf){//特判
        	cout<<"18446744073709551616"<<endl;
        	continue;
	}
        for(int i=1;i<=8;i++){
            ans+=mix(a[i]);
        }
        ans+=a[9];
        printf("%llu\n",ans);
    }
    return 0;
}//测试数据
/*
1
60 60 60 60 60 60 60 60 9223372036854775808
*/
/*
1
60 58 59 59 58 60 58 58 1993031419930314
*/
/*
2
60 60 60 60 60 60 60 60 9223372036854775808
60 58 59 59 58 60 58 58 1993031419930314
*/

代码如果不太好看不要喷我哈~

                                    Problem B: 新数独

                                                                Time Limit: 1000 ms    Memory Limit: 128 MB

Description


Input

输入一共 15 行,包含一个新数独的实例。第奇数行包含左右方向的符号( < > ),第偶数行包含上下方向的符号( ^ v )。

Output

输出包含 9 行,每行 9 1~9 的数字,以单个空格隔开。输入保证解惟一。

Sample Input

< >   > <   > <

v v ^ ^ v v ^ ^ ^

 < <   > <   > <

^ ^ ^ v ^ ^ ^ v v

 < <   < <   > >

 > <   > >   > >

v ^ ^ ^ ^ v v v ^

 > >   > >   < >

v v ^ v ^ v ^ v ^

 > <   < >   > >

 < <   < <   > <

v ^ v v v v ^ ^ v

 < >   > <   < >

^ v v v ^ v ^ v v

 < >   < >   < >

Sample Output

4 9 1 7 3 6 5 2 8

2 3 7 8 1 5 6 4 9

5 6 8 2 4 9 7 3 1

9 1 3 6 5 4 8 7 2

8 5 4 9 7 2 1 6 3

7 2 6 3 8 1 9 5 4

3 4 9 5 6 8 2 1 7

1 8 5 4 2 7 3 9 6

6 7 2 1 9 3 4 8 5

哎,这题真的恶心了我好久,特别是输入。

其实记录好每行、每列、每个九宫格里数的关系,每个格子和它的上、左两个数之间的大小关系直接爆搜就好。

AC code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int l[10][10],up[10][10],n[15][10],m[15][10],g[10][10];
int a[10][10];
void print(){//输出
    for(int i=1;i<=9;i++){
        for(int j=1;j<=9;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
}
int cmp(int x,int y){
    return x>y?-1:1;
}
bool check(int x,int y,int n){
    if(cmp(n,a[x-1][y])!=up[x][y]&&up[x][y]!=0)return 0;//比较上下
    if(cmp(n,a[x][y-1])!=l[x][y]&&l[x][y]!=0)return 0;//比较左右
    return 1;
}
void dfs(int x,int y){
    for(int i=1;i<=9;i++){//试数
        if(!n[x][i]&&!m[y][i]&&!g[(x-1)/3*3+(y-1)/3+1][i]&&check(x,y,i)){//n数组记录每行,m数组记录每列,g数组记录每个九宫格
            n[x][i]=g[(x-1)/3*3+(y-1)/3+1][i]=m[y][i]=1;
            a[x][y]=i;//记录
            if(x==9&&y==9){//只要一个解
                print();
                exit(0);//赶紧溜了
            }
            else (y==9?dfs(x+1,1):dfs(x,y+1));
            n[x][i]=g[(x-1)/3*3+(y-1)/3+1][i]=m[y][i]=0;
            a[x][y]=0;
        }
    }
}
int main(){
    char ch[2];
    for(int i=1;i<=9;i++){//恶心的输入
        for(int j=1;j<=9;j++){//l数组记录左右的大小关系,up数组记录上下的大小关系
            if(j%3!=0){
                scanf("%s",ch);
                if(ch[0]=='>')l[i][j+1]=1;
                else l[i][j+1]=-1;
            }
        }
        if(i%3!=0){
            for(int j=1;j<=9;j++){
                scanf("%s",ch);
                if(ch[0]=='v')up[i+1][j]=1;
                else up[i+1][j]=-1;
            }
        }
    }
    dfs(1,1);//爆搜开始了~
    return 0;
}
/*
< >   > <   > <
v v ^ ^ v v ^ ^ ^
 < <   > <   > <
^ ^ ^ v ^ ^ ^ v v
 < <   < <   > >
 > <   > >   > >
v ^ ^ ^ ^ v v v ^
 > >   > >   < >
v v ^ v ^ v ^ v ^
 > <   < >   > >
 < <   < <   > <
v ^ v v v v ^ ^ v
 < >   > <   < >
^ v v v ^ v ^ v v
 < >   < >   < >
*/

                                    Problem C: 城市交通

                                                                 Time Limit: 1000 ms   Memory Limit: 128 MB

Description

由于牛奶市场的需求,奶牛必须前往城市,但是唯一可用的交通工具是出租车.教会奶牛如何在城市里打的.

给出一个城市地图,东西街区E(1≤E≤40),南北街区N(1≤N≤30).制作一个开车指南给出租车司机,告诉他如何从起点(用S表示)到终点(用E表示).每一个条目用空格分成两部分,第一个部分是方向(N,E,S,W之一),第二个是一个整数,表示要沿着这个方向开几个十字路口.如果存在多条路线,你应该给出最短的.数据保证,最短的路径存在且唯一.地图中“+”表示十字路口,道路用“I”和“一”表示.建筑和其他设施用“.”表示.下面是一张地图:

出租车可以沿着东,北,西,北,东开两个十字路口,以此类推.具体将由样例给出。

Input

第1行:两个用空格隔开的整数N和E.

第2到2N行:每行有2E-I个字符,表示地图.

Output

每行有一个表示方向的字母和一个表示要开几个十字路口的数字表示.

Sample Input

3 6
+-+-+.+-+-+
|...|.....|
+-+.+-+-+-+
..|.......|
S-+-+-+.E-+

Sample Output

E 1
N 1
W 1
N 1
E 2
S 1
E 3
S 1
W 1

有人说这题用广搜好,我觉得吧......用SPFA更好些

把每个 + 看成一个点,每个 | 或 - 看成一条边,然后跑一遍最短路即可。

(代码有点长,思路很清晰的,耐心看一看哈,看不下去的别喷我)

AC code:

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
int n,m,head[4800],len,dis[4800],lu[4800],s,t;
char ans[4805];
bool vis[4800];
struct edge{//边结构体
    int v,next;//v表示指向点,next表示与这条边同一出发点的另一条边
    edge(){}
    edge(int _v,int _next){//构造函数
        v=_v;
        next=_next;
    }
}e[9600];
char map[100][100];
void init(){//初始化
    len=0;
    memset(head,-1,sizeof(head));
}
void spfa(int u){//啥,你不会spfa?那我也无能为力了
    memset(dis,0x3f,sizeof(dis));
    dis[u]=0;
    lu[u]=s;
    queue<int> q;
    q.push(u);
    while(!q.empty()){
        u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];~i;i=e[i].next){
            int v=e[i].v;
            if(dis[v]>dis[u]+1){
                dis[v]=dis[u]+1;
                lu[v]=u;
                if(!vis[v]){
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}
int get(int x,int y){//get函数计算点的编号
    return (x-1)*m+y;
}
void add(int u,int v){//插入边
    e[len]=edge(v,head[u]);
    head[u]=len++;
}
int tot;
void find(int x){
    if(x==s)return;
    find(lu[x]);
    tot++;
    if(x==lu[x]+2)ans[tot]='E';
    if(x==lu[x]-2)ans[tot]='W';
    if(x==lu[x]+m*2)ans[tot]='S';
    if(x==lu[x]-m*2)ans[tot]='N';
}
int main(){
    init();
    cin>>n>>m;
    n=n*2-1;
    m=m*2-1;
    char ch;
    ch=getchar();
    for(int i=1;i<=n;i++){//输入,把S和E看成+
        for(int j=1;j<=m;j++){
            map[i][j]=getchar();
            if(map[i][j]=='S'){
                s=get(i,j);
                map[i][j]='+';
            }
            if(map[i][j]=='E'){
                t=get(i,j);
                map[i][j]='+';
            }
        }
        ch=getchar();
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i>=3){//插入边
                if(map[i-2][j]=='+'&&map[i-1][j]!='.'){
                    add(get(i-2,j),get(i,j));
                    add(get(i,j),get(i-2,j));
                }
            }
            if(j>=3){//还是插入边
                if(map[i][j-2]=='+'&&map[i][j-1]!='.'){
                    add(get(i,j-2),get(i,j));
                    add(get(i,j),get(i,j-2));
                }
            }
        }
    }
    spfa(s);//不多说,直接spfa
    find(t);//找答案
    for(int i=1;i<=tot;i++){//输出
        int p=0;
        while(ans[i]==ans[i+1]){
            p++;
            i++;
        }
        printf("%c %d\n",ans[i],p+1);
    }
    return 0;
}//数据看上面↑↑↑

                                    Problem D: 雷涛的小猫

                                                                  Time Limit: 2000 ms   Memory Limit: 128 MB

Description

Input

Output

Sample Input

3 10 2
3 1 4 10
6 3 5 9 7 8 9
5 4 5 3 6 9

Sample Output

8

HINT

直接动规,不多说。状态转移方程:@#¥%……%   我太懒了不想写  聪明人才看得懂。(老铁没毛病)

AC code:

#include<iostream>
#include<cstdio>
using namespace std;
int n,h,d,a[2005][2005],f[2005][2005];
int main(){
    scanf("%d%d%d",&n,&h,&d);
    int x,y;
    for(int i=1;i<=n;i++){//倒序存储
        scanf("%d",&x);
        for(int j=1;j<=x;j++){
            scanf("%d",&y);
            a[i][h-y+1]++;
        }
    }
    for(int i=1;i<=n;i++){
        int sum=0;
        for(int j=1;j<=d;j++){//在h-d+1之上的位置只能从树顶跳下来
            sum+=a[i][j];
            f[i][j]=sum;
        }
    }
    for(int i=d+1;i<=h;i++){//注意一下i和j与上面表示的是不同的
        int maxn=0;
        for(int j=1;j<=n;j++)maxn=max(maxn,f[j][i-d]);
        for(int j=1;j<=n;j++)f[j][i]=max(maxn,f[j][i-1])+a[j][i];
    }
    int ans=0;
    for(int i=1;i<=n;i++)ans=max(ans,f[i][h]);
    cout<<ans;
    return 0;
}
呼,终于写完了,第一次写博客,大家多多支持下哈!

                                                                                                                                                           

《餐馆点餐管理系统——基于Java和MySQL的课程设计解析》 在信息技术日益发达的今天,餐饮行业的数字化管理已经成为一种趋势。本次课程设计的主题是“餐馆点餐管理系统”,它结合了编程语言Java和数据库管理系统MySQL,旨在帮助初学者理解如何构建一个实际的、具有基本功能的餐饮管理软件。下面,我们将深入探讨这个系统的实现细节及其所涉及的关键知识点。 我们要关注的是数据库设计。在“res_db.sql”文件中,我们可以看到数据库的结构,可能包括菜品表、订单表、顾客信息表等。在MySQL中,我们需要创建这些表格并定义相应的字段,如菜品ID、名称、价格、库存等。此外,还要设置主键、外键来保证数据的一致性和完整性。例如,菜品ID作为主键,确保每个菜品的唯一性;订单表中的顾客ID和菜品ID则作为外键,与顾客信息表和菜品表关联,形成数据间的联系。 接下来,我们来看Java部分。在这个系统中,Java主要负责前端界面的展示和后端逻辑的处理。使用Java Swing或JavaFX库可以创建用户友好的图形用户界面(GUI),让顾客能够方便地浏览菜单、下单。同时,Java还负责与MySQL数据库进行交互,通过JDBC(Java Database Connectivity)API实现数据的增删查改操作。在程序中,我们需要编写SQL语句,比如INSERT用于添加新的菜品信息,SELECT用于查询所有菜品,UPDATE用于更新菜品的价格,DELETE用于删除不再提供的菜品。 在系统设计中,我们还需要考虑一些关键功能的实现。例如,“新增菜品和价格”的功能,需要用户输入菜品信息,然后通过Java程序将这些信息存储到数据库中。在显示所有菜品的功能上,程序需要从数据库获取所有菜品数据,然后在界面上动态生成列表或者表格展示。同时,为了提高用户体验,可能还需要实现搜索和排序功能,允许用户根据菜品名称或价格进行筛选。 另外,安全性也是系统设计的重要一环。在连接数据库时,要避免SQL注入攻击,可以通过预编译的PreparedStatement对象来执行SQL命令。对于用户输入的数据,需要进行验证和过滤,防止非法字符和异常值。 这个“餐馆点餐管理系统”项目涵盖了Java编程、数据库设计与管理、用户界面设计等多个方面,是一个很好的学习实践平台。通过这个项目,初学者不仅可以提升编程技能,还能对数据库管理和软件工程有更深入的理解。在实际开发过程中,还会遇到调试、测试、优化等挑战,这些都是成长为专业开发者不可或缺的经验积累
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值