java的学习,oju的搜索题目,atc和cf的补题

阅读: 评论:0

java的学习,oju的搜索题目,atc和cf的补题

java的学习,oju的搜索题目,atc和cf的补题

目录

Java

缓冲字符流

输入

输出

转换流

输入

输出

对象流

随机存储流

class类

OJU

简单搜索&&进阶搜索 - Virtual Judge​​​​​​​

简单搜索&&进阶搜索 - Virtual Judge

简单搜索&&进阶搜索 - Virtual Judge

atc

E - 2xN Grid

cf

Problem - E - Codeforces

Problem - G1 - Codeforces


Java

缓冲字符流

输入

从计算机内部读文件到屏幕上。

import java.io.*;public class Test2 {public static void main(String[] args) {try {Test2.hczfsr();} catch (IOException e) {throw new RuntimeException(e);}}public static void hczfsr() throws IOException {FileReader r=new FileReader("D:\IDEA\java11\");BufferedReader br=new BufferedReader(r);char[] c=new char[100];int len=0;while((len= br.read(c))!=-1){System.out.println(new String(c,0,len));}br.close();r.close();}
}

主要代码:

创建一个文件字符流的参数,读取文件中的字符。

 FileReader r=new FileReader("D:\IDEA\java11\");

 缓冲字符的输入流,这个里面放FileReader的参数,表示缓冲这个文件中的字符。

BufferedReader br=new BufferedReader(r);

输出

从屏幕上写到计算机内部。

import java.io.*;public class Test2 {public static void main(String[] args) {try {Test2.hczfsc();} catch (IOException e) {throw new RuntimeException(e);}}public static void hczfsc() throws IOException {FileWriter fw=new FileWriter("D:\IDEA\java11\");BufferedWriter bw= new BufferedWriter(fw);String s="wcbwcbwcb";bw.write(s);bw.flush();bw.close();fw.close();}
}

主要代码:

创建一个参数,表示要新建的一个文件,也就是我之后要写入的文件。

FileWriter fw=new FileWriter("D:\IDEA\java11\");

缓冲字符的输入流,参数放我要写入的文件。 

BufferedWriter bw= new BufferedWriter(fw);

定义一个字符串,是我将要写入文件的字符。 

String s="wcbwcbwcb";
bw.write(s);//写入bw.flush();//刷新到硬盘bw.close();//关闭fw.close();//关闭,从后往前依次关闭

转换流

输入

import java.io.*;public class Test2 {public static void main(String[] args) {try {Test2.zhsr();} catch (Exception e) {throw new RuntimeException(e);}}public static void zhsr()throws Exception{FileInputStream fs=new FileInputStream("D:\IDEA\java11\TT4.TXT");InputStreamReader in=new InputStreamReader(fs,"UTF-8");char[] c=new char[100];int len=0;while((len&#ad(c))!=-1){System.out.println(new String(c,0,len));}in.close();fs.close();}
}

 主要代码:

建立一个输入流

FileInputStream fs=new FileInputStream("D:\IDEA\java11\TT4.TXT");

把字节流转换为字符流(UTF-8是中文编码),放置的参数分为两个,第一个是要输入的文件,第二个是使用的编码。

InputStreamReader in=new InputStreamReader(fs,"UTF-8");

输出

import java.io.*;public class Test2 {public static void main(String[] args) {try {Test2.zhsr();} catch (Exception e) {throw new RuntimeException(e);}}public static void zhsr()throws Exception{FileOutputStream fs=new FileOutputStream("D:\IDEA\java11\TT4.TXT");OutputStreamWriter out=new OutputStreamWriter(fs,"UTF-8");out.write("郭皓怡");out.flush();out.close();fs.close();}
}

主要代码:

 建立一个输出流,放置要输出的文件。

FileOutputStream fs=new FileOutputStream("D:\IDEA\java11\TT4.TXT");

确定编码格式 

OutputStreamWriter out=new OutputStreamWriter(fs,"UTF-8");

要记得刷新。

对象流

 

序列化和反序列化的示例代码:

import java.io.*;public class Test2 {public static void main(String[] args){try {Deserialize();} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}public static void testSerialize() throws IOException {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("D:\IDEA\java11\tt.txt"));Person p=new Person();p.name="zhangsan";p.age=11;out.writeObject(p);out.flush();out.close();}public static void textDeserialize() throws IOException, ClassNotFoundException {ObjectInputStream in=new ObjectInputStream(new FileInputStream("D:\IDEA\java11\TT.TXT"));Object obj&#adObject();Person p=(Person)obj;System.out.println(p.name);System.out.println(p.age);in.close();}}

注意:对象的序列化和反序列化使用的类要严格一致,包名、类名、类结构等等所有都要一致。

随机存储流

  

 示例代码如下:

import java.io.*;public class Test2 {public static void main(String[] args) {try {stRandomAccessFileRead();} catch (IOException e) {throw new RuntimeException(e);}}public static void testRandomAccessFileRead() throws IOException {RandomAccessFile ra=new RandomAccessFile("D:\IDEA\java11\","r");ra.seek(6);byte[] b=new byte[1024];int len=0;while((len&#ad(b))!=-1){System.out.println(new String(b,0,len));}ra.close();}
}

主要代码如下:

两个参数,文件路径和读取方式。

RandomAccessFile ra=new RandomAccessFile("D:\IDEA\java11\","r");

随机读取的关键,参数是确定读取(写入)的起始位置。 

ra.seek(6);

附加:

把写入的追加在最后面。

 

class类

 

 

 

OJU

前言

因为我是职高生,所以用了三四年C语言了,就一直不是很有欲望从C语言转成C++,但是!!!C++真的香,方便很多,就突然觉得C++也不是不可以,特别是最近接触了状压dp和优先队列之后,那是香了,就算是用在bfs里面也香啊。

 

简单搜索&&进阶搜索 - Virtual Judge

分析:

这个题我刚开始看见的时候,奇奇怪怪有点懵,然后写了一遍,果然时间超限。。。。。。

进入正题

 反转一个位置,它周围的四个格子也会跟着反转,那也就是说我想让一个格子反转,我最多有5种方法,那比下来数量是很大的,肯定会时间超限,所以这个时候有一个新的想法,先把第一行全部至于0的情况有多少种,找出最少的,然后再用第三行去反转第二行,第四行去反转第三行,依次反转,直至最后一行,如果发现最后一行依旧有没有被反转的1,那就输出“IMPOSSIBLE”,如果都反转完了,那就输出最少的需要反转的二维的格子。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
int m,n,sum=1e9+7;
int b[5][2]={{0,0},{0,-1},{0,1},{-1,0},{1,0}};
int a[16][16],c[16][16],d[16][16];int cz(int x, int y)
{int k = a[x][y]; for(int i=0; i<5; i++){int nx = x + b[i][0];int ny = y + b[i][1];if(nx>=0 && nx<m && ny>=0 && ny<n){k += c[nx][ny];}}return k % 2; 
}int ss()
{for(int i=1; i<m; i++){ for(int j=0; j<n; j++){ if(cz(i-1, j) == 1){ c[i][j] = 1;}}}for(int j=0; j<n; j++){if(cz(m-1, j) == 1) return -1; }int ct = 0;for(int i=0; i<m; i++){for(int j=0; j<n; j++){ct += c[i][j];}}return ct;
}void solve()
{for(int i=0; i<(1<<m); i++){ for(int j=0;j<m;j++)for(int k=0;k<n;k++)c[j][k]=0;for(int j=0; j<n; j++){c[0][j] = (i>>j) & 1; }int s = ss(); if(s>=0&&(s<sum)){sum = s;for(int j=0;j<m;j++)for(int k=0;k<n;k++)d[j][k]=c[j][k];}}if(sum == 1e9+7) printf("IMPOSSIBLE");else {for(int i=0; i<m; i++){for(int j=0; j<n; j++){printf("%d ", d[i][j]);}printf("n");}}
}int main()
{scanf("%d%d",&m,&n);for(int i=0;i<m;i++)for(int j=0;j<n;j++)scanf("%d",&a[i][j]);solve();//for(int i=0;i<m;i++)//for(int j=0;j<n;j++)//printf("%d",c[i][j]);
}

简单搜索&&进阶搜索 - Virtual Judge

分析:

这个题目我是打算用深搜的,但是果不其然,超了,那没有办法我只有重操旧业,选择了时间复杂度和空间复杂度都中规中矩的IDA*算法,IDA*算法是A*算法和迭代加深算法的结合,迭代加深算法是在dfs搜索算法的基础上逐步加深搜索的深度,它避免了广度优先搜索占用搜索空间太大的缺点,也减少了深度优先搜索的盲目性。它主要是在递归搜索函数的开头判断当前搜索的深度是否大于预定义的最大搜索深度,如果大于,就退出这一层的搜索,如果不大于,就继续进行搜索。这样最终获得的解必然是最优解。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
int n;
char a[10][6];
int min;
char s[4]={'A','C','G','T'};
int l1[20];//字符串的长度
int l2[20];//子串在母串中匹配到的位置int get()
{int max=0;for(int i=1;i<=n;i++){max=max>(l1[i]-l2[i])?max:(l1[i]-l2[i]);}return max;
}int dfs(int bs)
{if(bs+get()>min)return 0;if(!get())return 1;int l22[20];for(int i=0;i<20;i++)l22[i]=l2[i];for(int i=0;i<4;i++){int k=0;for(int j=1;j<=n;j++){if(a[j][l2[j]]==s[i])k=1,l2[j]++;}if(k){if(dfs(bs+1))return 1;for(int kk=0;kk<20;kk++)l2[kk]=l22[kk];}}return 0;
}void idax()
{while(!dfs(0))min++;
}int main()
{int t;scanf("%d",&t);while(t--){for(int i=0;i<20;i++){l1[i]=0;l2[i]=0;}scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%s",a[i]);l1[i]=strlen(a[i]);}idax();printf("%dn",min);min=0;}
}

分析:

这个题呢?我其实是很熟悉的,因为我进实验室写的那个连我自己都看不下去的项目就是九宫格,所以我非常清楚它的寻址方法,因为我之前的那个项目里面我就是用的IDA*算法,所以我想试一下A*算法,我开始是用c++写的,但是它一直编译出错,我后来就是用c写的,A*算法它是基于bfs的,所以它是以bfs为基础,进阶的一个搜索。

然后在这个题里面它加了一个记录,记录走过的路径,还有就是康拓。

 这里就是康托的那部分,康托展开的实质是计算当前排列在所有由小到大全排列中的顺序。

康拓最主要的还是这个公式。 

代码如下:

#include<stdio.h>
#include<string.h>
#define M 400000
char s[10]="12345678x";
char c;
char e[10],f[50];
char u[10]={'u','d','l','r'};
char ans[M][40],pos[200];
int bfg[M];
int d[4]= {3,-3,1,-1};
int dk[10];
struct node
{char a[40],b[10],x;
} p[M];void swap(char s[],int x,int y)
{char t=s[x];s[x]=s[y];s[y]=t;
}void fz(char s1[],char s2[])
{int n=strlen(s2),i;for(i=0; i<n; i++)s1[i]=s2[i];s1[i]='';
}int xz(char s[])
{int sum=0;for(int i=0; i<9; i++){int k=0;for(int j=i+1; j<9; j++)if(s[i]>s[j])k++;sum+=k*dk[8-i];}return sum+1;
}void bfs()
{int r=1,l=-1,i,j,t;fz(p[0].b,s);p[0].x=8;t=xz(s);bfg[t]=1;while(++l<r){for(i=0; i<4; i++){int xx=p[l].x+d[i];fz(e,p[l].b);if(xx>=0&&xx<=8){if(i==2){if(p[l].x==2||p[l].x==5)continue;}if(i==3){if(p[l].x==3||p[l].x==6)continue;}swap(e,p[l].x,xx);t=xz(e);if(bfg[t]==0){bfg[t]=1;fz(f,p[l].a);int n=strlen(f);f[n]=u[i];fz(ans[t],f);fz(p[r].a,f);fz(p[r].b,e);p[r].x=xx;r++;}}}}
}
int main()
{int i;dk[0]=1;for(i=1; i<10; i++)dk[i]=dk[i-1]*i;bfs();while(~scanf("%c",&c)){char ss[10]="123456789";for(i=0; i<9;){if((c>='1'&&c<='8')||c=='x'){s[i++]=c;}scanf("%c",&c);}int t=xz(s);if(bfg[t]==0)printf("unsolvablen");else{int n=strlen(ans[t]);for(i=n-1;i>=0;i--)printf("%c",ans[t][i]);printf("n");}}return 0;
}

简单搜索&&进阶搜索 - Virtual Judge

分析:

这道题和上面的那道题不是一个时间做的,但是很明显能想到用康拓和A*,其实原理都是一样的,就是换位置来达到最终的目的顺序,但是代码会更臃肿一些,毕竟上面的那个题就四个方向跑,这个题目它有点“乱跑”,所以要分块写,就有点麻烦。

代码如下:

#include<map>
#include<queue>
#include<string>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=500010;
int cun[10], mq[10], mb[10];
int cji[] = {1,1,2,6,24,120,720,5040,40320};
struct ff
{char bs;int sm;
}t[maxn];struct ffff 
{int a[10];int cantor;
};int ct(int *a) 
{int ans=0;for(int i=1;i<=8;i++) {int k=0;for(int j=i+1;j<=8;j++) {if(a[i]>a[j]) {k++;}}ans+=k*cji[8-i];}return ans;
}void A(int *a) 
{swap(a[1],a[5]);swap(a[2],a[6]);swap(a[3],a[7]);swap(a[4],a[8]);
}void B(int *a) 
{swap(a[3],a[4]);swap(a[7],a[8]);swap(a[2],a[3]);swap(a[6],a[7]);swap(a[1],a[2]);swap(a[5],a[6]);
}void C(int *a) 
{swap(a[2],a[3]);swap(a[2],a[7]);swap(a[2],a[6]);
}void get()
{for(int i=0;i<=maxn;i++) {t[i].sm=-1;}
}
void bfs() 
{queue<ffff> q;ffff S;for(int i=1;i<=8;i++) {S.a[i]=i;}S.cantor=0;q.push(S);while(!q.empty()) {ffff now=q.front();q.pop();ffff next=now;A(next.a);next.cantor=ct(next.a);if(t[next.cantor].sm==-1) {t[next.cantor].sm=now.cantor;t[next.cantor].bs='A';q.push(next);}next=now;B(next.a);next.cantor=ct(next.a);if(t[next.cantor].sm==-1) {t[next.cantor].sm=now.cantor;t[next.cantor].bs='B';q.push(next);}next=now;C(next.a);next.cantor=ct(next.a);if(t[next.cantor].sm==-1) {t[next.cantor].sm=now.cantor;t[next.cantor].bs='C';q.push(next);}}
}
int main() 
{char ks[10],js[10];get();bfs();while(~scanf("%s %s",ks,js)) {for(int i=0;i<strlen(ks);i++) {cun[i+1]=ks[i]-'0';}swap(cun[5],cun[8]);swap(cun[6],cun[7]);for(int i=1;i<=8;i++) {mq[cun[i]] = i;}for(int i=0;i<strlen(js);i++) {mb[i+1]=js[i]-'0';}swap(mb[5],mb[8]);swap(mb[6],mb[7]);for(int i=1;i<=8;i++){mb[i]=mq[mb[i]];}int hl=ct(mb);int sum=0;char kkk[1000];while(hl) {kkk[++sum]=t[hl].bs;hl=t[hl].sm;}for(int i=sum;i>=1;i--) {cout << kkk[i];}cout << endl;}return 0;
}

atc

E - 2xN Grid

分析:

这个题目我能怪有道翻译吗?不能,它真的翻得我脑浆都要出来了,都没有看懂。

这个题目题意是给我们一面长度为L的墙,分为上下两部分,每个部分都会有L列。现如今我们给出一个N1和N2,N1代表的上面墙给出的数据组数,N2表示的是下面的墙有多少组数据。每一组数据都是由两个数组成的,分别是数和长度。例如1  2表示的就是在开始的位置连续两个方块都是1。3  2表示的就是从上一次结束的位置开始我们由2块方块上写着3。最后让我们求出一共会有多少列的数据是一样的。

所以它就是一个普普通通的模拟加双指针。

代码如下:

#include<iostream>
#include<string.h>
using namespace std;
#include<stdio.h>
#include<math.h>
#include<string.h>
long long a[100005*2],b[100005*2],l,n,m;
long long jl,jnn,sum;
//long long min(int aa,int bb)
//{//  return aa<bb?aa:bb;
//}int main()
{ ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);scanf("%lld%lld%lld",&l,&n,&m);for(int i=0;i<n+m;i++){scanf("%lld",a+i);scanf("%lld",b+i);}jnn=n;for(int i=0;i<n+m;i++){if(a[jl]==a[jnn])sum+=min(b[jl],b[jnn]);if(b[jl]>b[jnn]){b[jl]-=b[jnn];jnn++;}else {b[jnn]-=b[jl];jl++;}}printf("%lld",sum);
}

cf

Problem - E - Codeforces

分析:

这是一个交互题,这个题我开始是有点懵的,因为我是在高中的时候接触过一次这样类型的题,它主张一个字“猜”,当然不是漫无目的随意妄为的猜,是要符合它给你的条件的“猜”,你可以先猜一边,然后它会告诉你符不符合,如果不符合,那么那块奇异的石头就在你没有猜到的另一边,这就是一个典型的二分查找,但是这个二分查找结合了前缀和,这样子的话,时间复杂度就好看点。

当然,它还有一个我以前没有接触过的点——“刷新”。如下:

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
int t;
int n;
int a[200005];
long long qh[200010];void sr()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",a+i);qh[i]=qh[i-1]+a[i];}
}int pd(int aa,int bb)
{if(aa==bb)return 1;return 0;
}int main()
{scanf("%d",&t);while(t--){qh[0]=0;sr();int l,r;l=1;r=n;int sum=0,mid;while(l<=r){mid=(l+r)/2;printf("? ");printf("%d ",mid-l+1);for(int i=l;i<=mid;i++)printf("%d ",i);printf("n");fflush(stdout);int aa;scanf("%d",&aa);if(pd(aa,qh[mid]-qh[l-1]))l=mid+1;else {r=mid-1;sum=mid;}}printf("! %dn",sum);fflush(stdout);}}

Problem - G1 - Codeforces

分析:

看见这道题的时候,我就在想,我为什么非得死磕一道题,不往后面看,这个题目真的好好好简单,排序+前缀和,排序我用的归并排序(中规中矩)。

这道题的思想就是先把我要搞出来的数组排序,然后从1开始,一次前缀和加上去,如果我的下一项大于它前面的前缀和就是“NO”,如果一整个数组都能搞出来就是“YES”,然后它的加强版就是把“int”改成“long long ”,然后再把数组开大点(这一点得看数据的,不是想开多少就开多少。)

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
long long t;
long long n;
long long a[200005];
long long b[200005];
long long sum=1;
void sr()
{scanf("%lld",&n);for(long long i=0;i<n;i++){scanf("%lld",a+i);b[i]=0;}
}long long funsort( long long a[], long long b[], long long left, long long mid, long long right)
{long long i,j,k;i=k=left;j=mid+1;while(i<=mid&&j<=right){if(a[i]>a[j]){b[k]=a[j];j++;k++;}else{b[k]=a[i];k++;i++;}}while(i<=mid)b[k++]=a[i++];while(j<=right)b[k++]=a[j++];for(i=left;i<k;i++)a[i]=b[i];
}long long fun( long long a[], long long b[], long long left, long long right)
{if(left<right){long long mid=(left+right)/2;fun(a,b,left,mid);fun(a,b,mid+1,right);funsort(a,b,left,mid,right);}
}int pd()
{if(a[0]!=1)return 0;for(long long i=1;i<n;i++){if(sum<a[i])return 0;sum+=a[i];}return 1;
}int main()
{long long t;scanf("%lld",&t);while(t--){sum=1;sr();fun(a,b,0,n-1);if(pd())printf("YESn");else printf("NOn");}
}

总结:这次的cf因为是div4所以是简单很多的,但是犯了两个常识性的错误,导致了D题时间超限,当时不应该看见E题F题就不往后看了,这死磕一题的毛病得改。

本文发布于:2024-02-08 19:48:39,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170739304868475.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:题目   oju   java   atc   cf
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23